{"version":3,"sources":["a3.cabin.app.js","a3.cabin.main.js","app.module.js","Campaigns/AssignmentModal.controller.js","app.route.js","app.run.js","app.settings.js","app.version.js","Graph.settings.js","MyDirectives.module.js","AirportContacts/AirportContacts.service.js","AirportHotels/AirportHotels.service.js","Bucket/Bucket.controller.js","Bucket/Bucket.service.js","Bucket/BucketDayInfo.controller.js","Bucket/BucketModal.controller.js","Bucket/Proposal.directive.js","Bucket/ProposalInfo.controller.js","Assessment/Assessment.controller.js","Assessment/AssessmentSyncResult.service.js","Assessment/CrewAssessment.service.js","Assessment/CrewAssessmentCreator.service.js","Assessment/CrewAssessmentMember.service.js","Assessment/CrewAssessmentTemplate.service.js","Campaigns/Campaigns.service.js","Common/Bytes.filter.js","Common/DataCleaner.service.js","Common/fltSplit.filter.js","Common/GenericModal.service.js","Common/GenericService.service.js","Common/GenericValues.service.js","Common/IndexedDB.service.js","Common/ModalDialogResult.service.js","Common/PushNotifier.service.js","Common/Search.filter.js","Common/Settings.service.js","Common/TimeLog.service.js","Common/Updater.service.js","Common/Utilities.js","Directives/basic-footer.directive.js","CrewCheckIn/CheckIn.service.js","CrewCheckIn/CrewCheckInModal.js","CrewExpiries/Expiries.servise.js","CrewInfo/CrewCall.contoller.js","CrewInfo/CrewCall.service.js","CrewInfo/CrewCheckIn.service.js","CrewInfo/CrewInfo.directive.js","CrewInfo/CrewPreviousInfo.directive.js","CrewInfo/LogCall.service.js","CrewInfo/PreviousDuty.service.js","CrewRoute/CrewContactsModal.controller.js","CrewRoute/CrewHotels.service.js","CrewRoute/CrewMeals.service.js","CrewRoute/CrewRoute.controller.js","CrewRoute/CrewRoute.service.js","CrewRoute/CrewRouteRefreshModal.controller.js","Customer/CustomerModalCtrl.js","Directives/aircraft-differences.directive.js","Directives/autoRefreshFlight.directive.js","Directives/campaigns.directive.js","Directives/crew-meals.directive.js","Directives/event-history.directive.js","Directives/flight-crew.directive.js","Directives/flight-footer.directive.js","Directives/flight-header.directive.js","Directives/ground-crew.directive.js","Directives/ground-header.directive.js","Directives/ground-information.directive.js","Directives/ground-services.directive.js","Directives/issues.directive.js","Directives/main-footer.directive.js","Directives/memos-by-category.directive.js","Directives/reports-panel.directive.js","Directives/security-search.directive.js","Directives/showErrorMessage.directive.js","Directives/ssr.directive.js","Directives/update-confirm.directive.js","Extenders/Array.js","Extenders/Date.js","Flights/FlightCrewMember.service.js","FlightServiceEvents/serviceEvents.directive.js","GroundDuties/GroundDuty.controller.js","Helpers/http401interceptor.service.js","Messages/Message.service.js","Report/ReportGuid.service.js","SWUpdate/SWUpdate.service.js","Training/competences.directive.js","Training/FlightCourse.controller.js","Training/media.directive.js","Training/training-menu.directive.js","Extenders/String.js","FaceMasks/faceMasks.directive.js","FaceMasks/FaceMasks.service.js","FAQs/Faq.service.js","FAQs/Faqs.controller .js","FAQs/FaqsModal.controller.js","FlightInformation/AimsCrewMemos.directive.js","FlightInformation/AimsCrewMemos.service.js","FlightInformation/AircaftPositions.service.js","FlightInformation/AircraftDifferences.service.js","FlightInformation/CrewRouteInfoPanel.directive.js","FlightInformation/FlightConfig.controller.js","FlightInformation/FlightDelays.service.js","FlightInformation/FlightGate.controller .js","FlightInformation/FlightGate.service.js","FlightInformation/FlightInfo.controller.js","FlightInformation/FlightStatus.directive.js","FlightInformation/GroundServices.service.js","FlightInformation/passengerEvents.directive.js","FlightInformation/PaxName.filter.js","FlightInformation/SyncPax.controller.js","FlightInformation/TurnAroundTimes.directive.js","Flights/AddFlight.controller.js","Flights/Calendar.controller.js","Flights/Flight.service.js","Flights/ReminderModal.controller.js","FlightServiceEvents/eventFormModal.controller.js","FlightServiceEvents/serviceEvents.service.js","GroomingCategories/GroomingCategories.service.js","GroomingCategories/GroomingCategoriesModal.controller.js","GroundDuties/GDCrewInfo.directive.js","GroundDuties/GroundDuty.service.js","GroundDuties/SearchPastGD.controller.js","GroundDuties/SearchPastGD.service.js","Helpers/compileProvider.config.js","Helpers/exceptionHandler.config.js","Helpers/httpCrewTokenInterceptor.service.js","Helpers/httpHeaderInterceptor.service.js","Helpers/httpProvider.config.js","Helpers/localStorageMD5.config.js","Helpers/Log.service.js","Helpers/UserToken.service.js","LeaveRequest/AnnualLeaves.directive.js","LeaveRequest/AnnualLeaves.service.js","LeaveRequest/FlexCombinations.directive.js","LeaveRequest/LeaveRequest.controller.js","LeaveRequest/LeaveRequest.service.js","LeaveRequest/LeaveRequestInstructions.controller.js","LeaveRequest/SpecificCombinations.directive.js","Login/CabinAPI.service.js","Login/Login.controller.js","Login/User.service.js","LuggageCompliance/LuggageCompliance.service.js","LuggageCompliance/twoLuggageEvents.directive.js","Memos/CalendarRedirectModal.controller.js","Memos/MandatoryModal.controller.js","Memos/Memo.service.js","Memos/MemoImages.service.js","Memos/MemoModal.controller.js","Memos/Memos.controller.js","Messages/Message.controller.js","Messages/message.filter.js","Messages/MessageModal.controller.js","OneStopShop/CustomerEvent.service.js","OneStopShop/CustomerEventHistory.service.js","OneStopShop/history.directive.js","OneStopShop/onestopshopEvent.directive.js","OneStopShop/Toolkit.service.js","PassengerMealServices/PassengerMeals.controller.js","PassengerMealServices/PassengerMealService.service.js","Passengers/Passenger.controller.js","Passengers/Pax.controller .js","Passengers/PaxInfo.service.js","Passengers/toolkit.directive.js","philoxeniaQuestions/PhiloxeniaQuestions.directive.js","philoxeniaQuestions/PhiloxeniaQuestions.service.js","Report/CabinReportLocalEdit.service.js","Report/CabinReportLocalEditCreator.service.js","Report/CabinReportRestore.service.js","Report/CabinReportSendToServer.service.js","Report/CabinReportSyncResult.service.js","Report/CabinReportTemplate.service.js","Report/Report.controller.js","Report/ReportsHistory.controller.js","Report/ReportsHistory.service.js","RosterRequests/Request.service.js","RosterRequests/requestForm.directive.js","RosterRequests/requestInstructions.controller.js","RosterRequests/requestItem.directive.js","RosterRequests/Requests.controller.js","Safety/Fatigue.controller.js","Safety/Safety.controller.js","Safety/SafetyReport.service.js","ScheduleAcknowledge/AcknowledgeModal.controller.js","ScheduleAcknowledge/ScheduleAcknowledge.service.js","SearchFlights/SearchFlights.controller.js","SearchFlights/SearchFlights.service.js","SearchFlights/SelectedFlight.controller.js","TraineeCourse/trainee-syllabus.directive.js","TraineeCourse/TraineeCourse.controller.js","TraineeCourse/traineeCoursesDetails.directive.js","TraineeCourse/TraineeCoursesDetails.service.js","Synch/InfoAPI.service.js","Synch/SyncAPI.service.js","Synch/Synch.controller.js","Synch/SyncLog.service.js","Ticket/Ticket.controller.js","Ticket/TicketAPI.service.js","Ticket/TicketModal.controller.js","TrainingReadOnly/additional-training-read-only.directive.js","TrainingReadOnly/competences-read-only.directive.js","TrainingReadOnly/course-read-only.directive.js","TrainingReadOnly/grading-read-only.directive.js","TrainingReadOnly/sector-history.directive.js","TrainingReadOnly/syllabus-progress-read-only.directive.js","TrainingReadOnly/syllabus-read-only.directive.js","Training/additionalTraining.directive.js","Training/AdditionalTrainingModalCtrl.controller.js","Training/certificate-exam.directive.js","Training/CompetenceModal.controller.js","Training/course-footer.directive.js","Training/course.directive.js","Training/Course.service.js","Training/FlightSession.service.js","Training/grading.directive.js","Training/GroundCourse.controller.js","Training/instructions.directive.js","Training/ModuleHistory.controller.js","Training/non-eligible-trainees.directive.js","Training/NotificationModal.controller.js","Training/notifications.directive.js","Training/releasable-module.directive.js","Training/release-warning.directive.js","Training/ReleaseSignatureModal.controller.js","Training/SignatureModal.controller.js","Training/syllabus-item-header.directive.js","Training/syllabus.directive.js","Training/TraineeSignatureModal.controller.js","Training/TrainingSession.service.js","Utilities/app.version.js","Utilities/Debug.controller .js","Utilities/Debug.service.js","Utilities/ResetDevice.controller.js","Wifi/wifiAvailability.servise.js","Wifi/wifiPrograms.directive.js","Wifi/wifiVouchers.directive.js","Wifi/WifiVouchers.service.js","Report/Modals/ACSupply.service.js","Report/Modals/AircraftType.service.js","Report/Modals/BarTrolley.controller.js","Report/Modals/BarTrolley.service.js","Report/Modals/CCMS.service.js","Report/Modals/CCMSCrewPosition.controller.js","Report/Modals/CCMSCrewPosition.service.js","Report/Modals/FirstAidKit.controller.js","Report/Modals/FirstAidKit.service.js","Report/Modals/FlightDetail.controller .js","Report/Modals/IncompleteServicesIssue.controller.js","Report/Modals/IncompleteServicesIssue.service.js","Report/Modals/IncompleteServicesSource.service.js","Report/Modals/ItemPhotos.controller.js","Report/Modals/MedicalIncident.controller .js","Report/Modals/MedicalIncident.service.js","Report/Modals/OpenReportDialog.controller .js","Report/Modals/Photo.service.js","Report/Modals/SeatChange.controller.js","Report/Modals/ServerCabinReport.service.js","Report/Modals/SpecialMealIssue.controller .js","Report/Modals/SpecialMealIssue.service.js","Report/Modals/SpecialMealSource.service.js","Report/Modals/SpecialMealType.service.js","Report/Modals/Supply.controller .js","Report/Modals/Supply.service.js","Report/Modals/TravelValueIncompleteReason.service.js","Report/Modals/TravelValueSeal.controller.js","Report/Modals/TravelValueSeal.service.js","Report/Modals/UPGD.controller.js","Report/Modals/WaterUpliftAction.service.js"],"names":["modalUpdates","isDownloanding","isCheckForUpdate","window","navigator","$","modal","backdrop","keyboard","show","removeClass","find","hide","success","addClass","setTimeout","noUpdate","failure","errorMessage","text","on","e","hasClass","location","reload","call","cacheHandler","cacheStatusValues","onDownloading","logEvent","onCached","onChecking","onProgress","onObsolete","onError","message","console","error","onNoUpdate","onUpdateReady","cache","swapCache","applicationCache","addEventListener","click","alert","url","origin","ajax","type","undefined","status","update","document","zIndex","this","parents","css","angular","bootstrap","a3_cabin_reports","module","ownKeys","object","enumerableOnly","keys","Object","getOwnPropertySymbols","symbols","filter","sym","getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","target","i","arguments","length","source","forEach","key","_defineProperty","getOwnPropertyDescriptors","defineProperties","defineProperty","obj","value","configurable","writable","routeConfig","$routeProvider","when","controller","templateUrl","reloadOnSearch","otherwise","redirectTo","config","runBlock","$rootScope","$timeout","$location","$anchorScroll","UserFactory","UserTokenFactory","$templateCache","SettingsMain","SWUpdateService","CabinReportLocalEditFactory","CrewAssessmentFactory","PaxInfoFactory","LogService","valid","$on","event","next","current","indexOf","$$path","isLoggedIn","preventDefault","path","initialize","serviceWorker","getRegistration","then","registration","SWRegistration","checkUpdates","yOffset","$$route","editingPage","getEditingPage","setEditingPage","getCabinReportLocalEditFromTemp","getTempAssessment","remove","idbSupported","isOffline","onLine","link","attr","debug","user","getUser","token","setToken","run","constant","clientId","tenantId","authority","code","description","barOptions","pieDoughnutOptions","scaleShowGridLines","scaleGridLineColor","scaleGridLineWidth","scaleShowHorizontalLines","scaleShowVerticalLines","bezierCurve","bezierCurveTension","pointDot","pointDotRadius","pointDotStrokeWidth","pointHitDetectionRadius","datasetStroke","datasetStrokeWidth","datasetFill","legendTemplate","segmentShowStroke","segmentStrokeColor","segmentStrokeWidth","percentageInnerCutout","animationSteps","animationEasing","animateRotate","animateScale","onAnimationComplete","showTooltip","segments","tooltipEvents","showTooltips","directive","restrict","scope","require","element","ctrl","sigPadAPI","signaturePad","drawOnly","lineColour","penWidth","clearbtn","clearCanvas","updateModel","sig","getSignature","$setViewValue","$render","$viewValue","regenerate","$parsers","unshift","viewValue","validateForm","$setValidity","template","sigdata","$observe","val","displayOnly","pic","getSignatureImage","$q","URL","webkitURL","maxwidth","maxheight","quality","imagetype","onfilechange","attrs","whenError","$apply","onFileFailureCallback","err","whenReady","img","src","HTMLCanvasElement","imageResult","dataURL","toDataURL","options","imageType","fileName","filename","fileType","onFileChangeCallback","data","onfileerror","bind","evt","dataTransfer","files","file","maxWidth","parseFloat","maxHeight","canvas","name","loadImage","parseMetaData","exif","orientation","get","elm","test","replace","keyCode","inArray","which","$eval","onlyNum","chartObject","chart","context","getContext","width","height","Chart","$watch","chartType","chartInstance","destroy","$scope","parseInt","render","ctx","clearRect","calcPercent","total","perc","per","min","max","pad","x","y","radius","lineWidth","fontSize","imageSmoothingEnabled","shadowOffsetX","shadowOffsetY","shadowBlur","beginPath","arc","Math","PI","strokeStyle","underColor","stroke","closePath","endAngle","overColor","font","textAlign","fillStyle","textColor","shadowColor","shadeColors","smallTextColor","fillText","mask","placeholder","toFixed","toString","animID","curValue","endValue","oldValue","direction","color","percent","f","slice","t","p","R","G","B","round","newval","oldval","getComputedStyle","getPropertyValue","animate","requestAnimationFrame","cancelAnimationFrame","input","isInvalid","toggleClass","AirportContactFactory","GenericService","objType","objCallback","Iata","Contacts","setAirportContactsToStorage","airportContacts","saveAll","fromObjectList","objList","getAirportContactsFromStorage","list","clearAirportContactsFromStorage","removeAll","getAirportContacts","airportIata","all","airport","item","upsertAirportContacts","newStations","map","contactsLS","includes","concat","factory","AirportHotelFactory","Hotels","setAirportHotelsToStorage","airportHotels","getAirportHotelsFromStorage","clearAirportHotelsFromStorage","getAirportHotels","fltDate","hotel","fltActiveHotels","HotelPriorities","ActiveBegin","ActiveEnd","ActivePriority","PriorityNo","upsertAirportHotels","newHotels","hotelsLS","BucketCtrl","BucketFactory","MessageFactory","defaultBucketDate","ownDuties","approvedDuties","state","isSecure","isUserSA","position","logged_user_info","aimsId","getCalendarData","showErrorMessage","selectedDate","getCalendarSelectedDate","progressBarBox","getDutyObject","responseData","Duties","SharedDuties","ApprovedDuties","number_of_messages","getMessagesFromStorage","number_of_messages_not_readen","getCountOfUnreadMessages","notification","duties","NewPendingProposalsCount","NewApprovedProposalsCount","NewRejectedProposalsCount","notificationText","IsUpdated","HasApprovedProposals","hasPrevious","createNotification","events","formatDuties","appvovedEvents","fullCalendar","defaultView","calendarStyle","getCalendarViewStyle","detectMobile","getDefaultView","defaultDate","firstDay","lang","editable","draggable","selectable","selectHelper","unselectAuto","disableResizing","droppable","fixedWeekCount","nextDayThreshold","header","left","center","right","timeFormat","displayEventEnd","eventOrder","eventRender","icon","prepend","each","className","index","listViewColor","icons","otherInfos","info","label","append","num","add","eventResize","delta","revertFunc","changeView","dayRender","date","cell","eventClick","calEvent","jsEvent","view","shareable","isOwnDuty","isApproved","isOwnApproved","bootbox","dialog","title","buttons","cancel","callback","dutyId","gotoDayBucketView","_id","setCalendarViewStyle","calendar","setupView","statusText","dutiesEvents","log","eClassName","getEventClassName","eIcons","getEventIcons","eTitle","getEventTitle","TotalSharedDuties","eOtherInfos","getOtherInfos","Id","start","DutyBegin","DutyEnd","DutyDateS","end","sortOrder","Shareable","duty","Shared","Title","eventClass","class","hasApprovedTrade","infos","PendingProposalsCount","BookmarksCount","innerWidth","innerHeight","setCalendarSelectedDate","isOpen","closeButton","hideAll","$http","apiUrl","Content-Type","getDutyById","shareDuty","errorCallback","dutyMinified","Comments","CrewInformation","Email","Phone","post","acknowledgeProposal","proposalId","fetchProposal","createProposal","proposal","evaluateProposal","put","undoProposalStatus","fetchSharedProposal","sharedDutyId","BucketDayCtrl","$routeParams","$uibModal","isSharedLate","selectedStates","currentDutyId","initialized","displayMessage","hasErrors","showResponse","responseText","responseHasErrors","confirmUnshare","confirm","getData","fromShareBtn","open","size","resolve","result","refresh","isLoading","currentDutyDate","totalItems","currentPage","today","Date","dutyDay","trimmedToday","trimmedDutyDay","diffDays","DifferenceInDays","trimTime","contains","getDay","getUTCHours","checkLateShare","approvedDuty","Status","initProposalsView","returnToBucket","activeTab","proposals","toggle","Accepted","Rejected","Pending","Bookmarks","getProposalBorderStyle","textclass","State","hasTimeChange","showMobileProposalCriteria","filterProposal","isShown","isAcknowledged","hasProposals","pageOptions","viewby","itemsPerPage","maxSize","setPage","pageNo","setItemsPerPage","BucketModalCtrl","$uibModalInstance","closeDuty","close","submitted","$filter","terminal","actionDisabled","sharedCount","updateProposal","newProp","errorCall","loading","insertInformation","ProposedDuties","RequestedDuties","HasMultiDuties","AllDuties","tableMaxRowLength","matchedDuty","Proposed","Requested","createDisabled","proposedDutiesIdList","requestedDutiesIdList","onSuccessMessage","onFailureMessage","previousStatus","confirmCreateProposal","successful","Duty","Array","fetch","viewInfoModal","id","getFirstInfoIcon","getSecondInfoIcon","hasSecondInfoIcon","getTextColor","getFirstActionIcon","hasFirstActionIcon","getSecondActionIcon","hasSecondActionIcon","getFetchIcon","getInfoMessage","firstAction","secondaryAction","showEndDate","DifferenceInMinutes","showTime","dutyCommentElipsis","charNo","comments","substring","showFullComment","toggleFullCommentVisibility","ProposalInfoModalCtr","allDuties","previous","AssessmentCtrl","orderByFilter","FlightFactory","minDate","maxDate","flightRouteString","flightId","crewAssessment","flight","getFlightFromStorage","FlightId","getCrewAssessmentFromStorage","assessment","flights","Flights","ScheduledArrival","ScheduledDepartureDateUTC","ScheduledDepartureTimeUTC","Departure","Arrival","route","Route","DutyDate","MinDate","MaxDate","FlightRoute","assessedBy","assessed","assesedBy","Name","isFirstOpen","togglePanel","panelId","isPanelOpen","infoSaveOperation","infosaveactiontype","infosaveaction","saveAssessment","setCrewAssessmentToStorage","updateFlightsAssessment","updateCrewRouteAssessment","clearRemarks","ItemDescr","Review","avgValue","items","sum","ItemValue","updateValues","crewMember","IsCompleted","trim","saveTempAssessment","isCompleted","j","CrewAssessmentMembers","IsExist","IsValid","IsOverride","IsSynched","assessments_not_completed","getCountOfUncompletedAssessments","saveClicked","clearTempAssessment","saveDraftClicked","assesmentCSSClass","assesmentIconClass","discard","AssessmentSyncResultFactory","getAssessmentSyncResultsFromStorage","setAssessmentSyncResultsToStorage","assessmentSyncResults","getSuccesses","syncResults","getFailures","localStorageMD5Service","CrewAssessmentMemberFactory","CrewAssessmentTemplateFactory","CrewRouteFactory","UserId","DutyDay","AcType","GetId","getCrewAssessmentsFromStorage","lsItems","save","getCrewAssessmentByRoute","crewAssessments","arrayLength","fromObject","existsForRouteDutyDate","assessments","isExist","updateAssessmentFlights","flightStart","parse","ScheduledDeparture","flightEnd","FlightNo","AcTailNo","setCrewAssessmentsToStorage","crewAssessmentId","count","getNewCrewAssessment","constructor","set","updateCrewMembers","CCMSPositions","crewAssessmentTemplate","getCrewAssessmentTemplateFromStorage","routeFlights","getFlightsByRoute","isChanged","isExists","CrewId","CCMS","isValid","h","localReport","getCabinReportLocalEditForFlight","CCMSCrewPositions","IsManual","newMember","assessmentItems","Position","shortname","Initials","getFlightsFromStorage","setFlightsToStorage","updateCrewAssessment","newAssessment","isUpdated","validCrewCount","outdatedCrewCount","nonExistentCrewCount","assessmentCrew","isCreated","IsOutdated","l","CrewAimsId","EndPeriod","newAssessmentItems","question","Description","Label","OrderNo","splice","getAssesedCabinReports","reports","getCabinReportsFromStorage","assesedReports","routeReports","cabinReportStatusDescr","sort","a","b","getAssementsReadyToSend","assessmentsToSend","storeFlightsWithAssessments","IsAssessedBy","IsCrewLess","storeCrewRoutesWithAssessments","crewRoutes","getCrewRoutesFromStorage","AssessmentInfo","setCrewRoutesToStorage","CrewAssessmentCreatorFactory","createNewCrewAssessment","crewAssessmentTemplates","guid","createCrewAssessments","CrewAssessmentMember","setCrewAssessmentTemplateToStorage","AssignmentModalCtrl","assignment","CampaignFactory","JSON","stringify","dismiss","submit","updateCampaignPassenger","giftStatus","giftStatusList","getFlightsCampaignsFromStorage","getCampaignsByFlightId","findCurrentAssignment","currentAssignment","currentCamps","_iteratorNormalCompletion8","_didIteratorError8","_iteratorError8","_step8","_iterator8","Symbol","iterator","done","flt","_iteratorNormalCompletion9","_didIteratorError9","_iteratorError9","_step9","_iterator9","CampaignsList","camp","_iteratorNormalCompletion10","_didIteratorError10","_iteratorError10","_step10","_iterator10","Treatments","Assignments","assign","saveFlightCampaignsToStorage","campaignPassenger","IsFeedbackReady","hasPendingFeedbacks","feedbackReadyCounter","_iteratorNormalCompletion13","_didIteratorError13","_iteratorError13","_step13","_iterator13","_iteratorNormalCompletion14","_didIteratorError14","_iteratorError14","_step14","_iterator14","AssignmentsCounter","assignmentLs","fltCampaings","_iteratorNormalCompletion11","_didIteratorError11","_iteratorError11","_step11","_iterator11","_iteratorNormalCompletion12","_didIteratorError12","_iteratorError12","_step12","_iterator12","treat","StatusStr","Rate","updateSeatNoPaxAssignments","paxinfoList","fltcamp","paxinfo","paxinfoFlatten","flatten","arr","reduce","flat","toFlatten","isArray","Seatmap","s","Columns","pax","PNR","UCI","SeatNo","getPaxAssignmentsFromStorage","assignmentsToSend","flightsReadyList","d","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_step","_iterator","flightStored","moment","valueOf","utc","assignToSend","FlightsToFetch","AssignmentsToUpdate","mergeCampaigns","flightIdList","UpdateAssignmentsSuccess","incomingfltIds","FlightsCampaigns","clearFlightCampaignsFromStorage","GetAssignmentsSuccess","incomingCamps","_iteratorNormalCompletion4","_didIteratorError4","_iteratorError4","_step4","_iterator4","_iteratorNormalCompletion5","_didIteratorError5","_iteratorError5","_step5","_iterator5","_iteratorNormalCompletion6","_didIteratorError6","_iteratorError6","_step6","_iterator6","_iteratorNormalCompletion7","_didIteratorError7","_iteratorError7","_step7","_iterator7","updateIncomingStore","FlightCampaigns","addFlightCampaigns","getPaxAssignment","pnr","uci","fltCampaigns","campaign","treatment","_iteratorNormalCompletion2","_didIteratorError2","_iteratorError2","_step2","_iterator2","CampaignTitle","briefings","Briefings","_iteratorNormalCompletion3","_didIteratorError3","_iteratorError3","_step3","_iterator3","syncResultFormat","updateText","upClass","fetchText","fetchClass","updMessage","updClass","ftcMessage","ftcClass","cleanOldCampaigns","pendingFlightIds","bytes","precision","isNaN","isFinite","number","floor","pow","DataCleanerFactory","IndexedDBService","deleteOrphanedLocalFlights","existingLocalFlights","finalLocalFlights","cabinReportLocalEdits","hasCabinReport","FlightAimsId","objCallbackRatings","CrewMealId","TimeStamp","deleteAllReports","deleteAllServerData","deleteAllData","clearAll","deleteDatabase","deleteOrphanedLocalReports","existingLocalCabinReports","finalLocalCabinReports","deleteSynchedLocalCabinReports","deleted","cabinReports","AuthorAimsId","deleteIndexedDB","deleteOldCrewMealsRatings","res","lastDate","setDate","getDate","crewMealIdsFiltered","r","saveOne","deleteOrphanedCustomerEvents","customerEvents","finalCustomerEvents","fltSplit","formattedFltNo","String","createNew","extend","deleteFromList","itemIndex","newobjList","objectType","initiate","objects","getOne","updatedobject","newObjects","saveByFilter","filters","retVal","storageObject","removeByFilter","GenericValuesFactory","newObjList","newObj","Code","getValuesFromStorage","setValuesToStorage","clearValuesFromStorage","getValuesFromStorageAsStrings","objs","init","deferred","defer","request","indexedDB","onupgradeneeded","db","oldVersion","createObjectStore","keyPath","createIndex","unique","gameStore1","objectStoreNames","store4","store","onsuccess","onerror","reject","promise","ex","onabort","storeName","tx","transaction","objectStore","indexNames","indexes","keypath","errorMsg","oncomplete","entity","addAll","getById","getByIndex","indexName","openCursor","IDBKeyRange","only","results","cursor","getAll","removeByIndex","openKeyCursor","primaryKey","clear","ModalDialogResult","IsInsertMode","PushNotifier","service","Generate","body","browserSupportsNotifications","Notification","permission","formatInfoToCompare","flightInfo","CTOT","ATD","ETA","ETD","DepartureGate","DepartureStand","getPaxInfoFromStorage","LastRun","format","compareAndExtractChanges","currentData","updatedData","changes","ovalue","nvalue","newValue","MessageGenerator","phrase","CheckForPermissionsAndSupport","permissionQ","requestPermission","itemArray","searchWords","toLowerCase","split","some","Tags","$log","PageMainSettings","EditingPage","IsAssessmentEnabled","calendarViewStyle","getSettings","settings","settingsStored","setSettings","getIsAssessmentEnabled","isEnabled","isDHC","setIsAssessmentEnabled","TimeLogFactory","TimeLog","ClientTimeLog","ApiTimeLog","timeLogToStorage","timeLogStr","apiTimelog","timeLog","cleanOldData","now","timeLogs","latestTimeLogs","diff","setTimeLogsToStorage","UpdateService","SyncLogFactory","updater","synclog","getSyncLog","patcher","version","NeedsSync","updateSyncVersion","s4","random","sort_by","field","reverse","primer","A","autoAdjustTextarea","scrollHeight","style","overflow","CheckInFactory","response","checkInInfo","setCheckInInfoToStorage","getCheckInInfoFromStorage","checkInFailedCallBack","responseString","checkIn","confirmed","Confirmed","ErrorExplanation","updateCheckInCallBack","saveCheckInDelay","delayMinutes","DelayMinutes","updateCheckInDelayCallBack","CheckInModalCtrl","$route","GetCheckInInfoFromServer","showContent","handleRefreshResponse","responseObj","handleSubmitResponse","handleDelayMessageResponse","CheckInAction","BackToActions","ConfirmCheckIn","SendDelayMessage","selectedDelayMinutes","onMinutesChange","minutes","numberDown","numberUp","ExpiriesFactory","expiries","showExpiriesModal","getCrewExpiriesFromStorage","setCrewExpiriesToStorage","crewExpiries","needsReminder","ExpiryTypeId","NeedsHardAlert","showExpiriesAlert","needsAlert","NeedsSoftAlert","updateShowExpiriesModal","canShowModal","CrewCallCtrl","crew","groundDutyId","CrewCallFactory","LogCallFactory","beforeCall","logData","Requester","Requestee","crewFixed","GroundDutyId","saveLogCall","LogCall","PhoneNumber","phoneNumber","getCrewCallsFromStorage","setCrewCallsToStorage","saveCrewCall","crewCall","getCrewCallFromStorage","crewId","getFlightCrewCallsFromStorage","responseFlightIds","phoneNumbers","keepingPhoneNumbers","dateSTD","STD","fromUTC","std","minFetchTime","dateSTA","STA","sta","maxFetchTime","isAfter","isBefore","cleanFlightCrewNumbers","saveFlightPhoneNumbers","FlightCheckInsFactory","CheckIn","WillBeThereAt","getCrewCheckInFromStorage","setCrewCheckInToStorage","updateFlightCrewCheckInToStorage","storedCheckInsFiltered","FlightInfo","getFlightCrewCheckInFromStorage","crewInfo","selectedflightid","aircraftroute","openPhoneConfirmation","showInfoRow","differentUser","phoneAvailable","previousDutyAvailable","PreviousDuty","isDifferent","phonesAvailable","checkInStatusAvailable","needsAdditionalFeedback","showArrivalFormat","previousDuty","formatedArrival","dateFormat","showArrivalDate","ATA","hiddenButtonHistory","crewMembers","positionOrder","getPaxInfoList","passengerList","matchedPassenger","IsDHC","Fullname","toUpperCase","seatNo","crewPreviousInfo","filterByPreviousDuty","getLogCallsFromStorage","cleanLogsFromStorage","PreviousDutyFactory","getPreviousDutiesFromStorage","setPreviousDutiesToStorage","savePreviousDuty","getPreviousDutyFromStorage","getFlightPreviousDutiesFromStorage","previousDuties","cleanFlightPreviousDuties","saveFlightPreviousDuties","CrewContactsModalCtrl","selectedFlightNo","closeCrewPanel","CrewHotelFactory","AimsId","CrewName","Base","Airport","HotelNo","HotelName","GroundTime","getCrewHotelsFromStorage","setCrewHotelsToStorage","getCrewHotelFromStorage","dutydate","crewHotels","Dutydate","CrewMealFactory","CateringMealId","ratingSubmitResponseObj","getCrewMealsFromStorage","setCrewMealsToStorage","getCrewMealFromStorage","cateringMealId","crewMeals","sendCrewMealsRatingReport","ratingForm","objectToAdd","saveReportSuccessCallBack","hasRating","crewMealId","getCrewMealsDidNotEatReasons","CrewRouteCtrl","GroundDutyFactory","dutyNo","crewRouteDuty","getCrewRouteFromStorage","groundDuties","getGroundDutiesByDutyNo","groundDuty","DutyType","Start","getFlightsByDutyNo","crewRoute","currentDutyDay","differentDay","day1","day2","openRefresh","crewroute","Number","forCurrentDay","transferData","sync","forceSync","firstFlightId","getFirstFlightId","AircaftPositionsFactory","FlightDelaysFactory","DutyNo","CrewMeals","LastRefreshed","getCrewRouteDuties","flightDate","getCrewRouteFlights","showNextAcPos","showPreviousAcPos","hasChangeAircraft","isFirst","isLast","BTime","Delay","ArrDelay","aircaftPositions","flightDelays","array","diffMin","MinutesToStringSimple","getAircaftPositionsByFlightId","PreviousFlightDelay","PreviousATD","PreviousSTD","PreviousFlightArrDelay","PreviousATA","PreviousSTA","diffPreviousFlightMin","PreviousFlightBTime","PreviousDelays","getFlightDelaysByFlightId","PreviousFlightId","NextFlightDelay","NextATD","NextSTD","NextFlightArrDelay","NextATA","NextSTA","diffNextFlightMin","NextFlightBTime","NextDelays","NextFlightId","crewRouteDuties","flightIds","cr","FlightIds","FlightDate","setCourseCompleted","courseId","crewRouteCourse","Courses","CourseId","isSame","flightCourse","updateFlight","setCoursePending","updateCrewMealsInRoute","newCrewMeals","newFlightIds","crewMealsInRoute","updateRouteLastRefreshDate","toDate","toUTC","getCrewRouteInfoPanel","crewRouteInfo","crewRouteFlightDuties","hasAircraftPositions","crewMealsPerFlightId","meals","CrewMealsCateringIds","crewMealsTitles","values","ShortTitle","routeNeedRefresh","updateCrewRouteDuty","flightTraining","addCrewRouteDuty","isManualEntry","hasPendingCourse","getManualFlightTrainingsFromStorage","removeFlightTraining","insertCrewRoutesWithPendingTrainings","instructorPendingRoutes","crewRoutesIdsLS","routesToInsert","updatedCrewRoutesList","CrewRouteRefreshModalCtrl","InfoAPIService","FlightSessionFactory","CourseFactory","LuggageComplianceFactory","GroundServicesFactory","AircraftDifferencesFactory","AimsCrewMemosFactory","CustomerEventHistoryFactory","FlightServiceEventsFactory","t0","performance","tFrom","tTo","isRefreshing","refreshResultsVisible","collapse","isCollapsed","crewRouteGeneral","statuses","currentDayDuties","CurrentDutyDate","datatype","DataStatus","isTraining","currentFlights","currentGroundDuties","refreshCrewRoute","responseStatuses","groundServices","aircraftDifferences","campaigns","crewAimsMemos","flightServiceEvents","AirportContacts","GroundServices","upsertGroundServices","AircraftDifferences","upsertAircraftDifferences","AirportHotels","CrewAimsMemos","upsertAimsCrewMemos","Campaigns","FlightDelays","upsertFlightDelays","OneStopShop","CustomerEventHistory","refreshPassengerHistory","FlightServiceEvents","upsertEvents","needsSynchCheck","newFlights","newGroundDuties","needsSynch","GroundDuties","updateCrewRouteStatusSetter","updateFlightStatusSetter","setupFlightInfo","updateFlightLocalStorage","updatePhiloxeniaQuestions","updateLuggageComplianceStorage","LuggageCompliance","updateCrewCheckIn","updateFlights","trainingCourses","TrainingCourses","trainingCourse","upsertCourse","course","applyTraineeInfoToSession","session","updateGroundStatusSetter","setupGroundInfo","updateGroundDutyLocalStorage","updateGroundDuties","Timelog","CustomerModalCtrl","customerIncident","sendCustomerIncident","flightDescription","image","attributes","AircraftDifferencesObj","getAircraftDifferenceFromStorageByRegistration","autorefresh","$interval","browserNotificationsEnabled","autoUpdateInterval","autoUpdateIntervalTimeOffset","showAlternativeNotifications","showAutoUpdatePanel","ScheduledDepartureTimeStamp","autoflightInfoInterval","intervalTime","departureTime","depTimestamp","nowTimeStamp","absoluteMinuteDiff","abs","timerDelayGenerator","currentInfo","getPax","getFlightFromTotalFlights","paxInfo","cStat","PaxTotalC","ConfigurationC","yStat","PaxTotalY","ConfigurationY","mealsChart","generateMealChart","listSentTimestamp","getTime","IsProvisional","crewRouteInfoPanel","flightETA","updatedInfo","DepartureEU","radioModel","basicFooter","gotoMessageLibrary","gotoFAQs","gotoRequests","gotoBucketCalendar","gotoCalendar","gotoMealLibrary","logout","clearActiveUser","azSignOut","_ref","checkForCompletion","c","assignmentsWithStatus","CompleteFeedbacksCount","feedbacksCompleted","every","FeedbacksCompleted","campaignCompleted","TreamentsCompleted","currentTreatment","previousTreatment","nextTreatment","lenght","openAssignment","cindex","isItemOpen","closed","$sce","HasRegChanged","noClicked","clearFormData","showPanel","yesClicked","submitRatingClicked","flightCrewMeals","CrewMealsDescriptions","findIndex","HasRating","manageResponseMessage","canceClicked","isFlightPanel","isRoutePanel","routeCrewMeals","showCrewMealsPanel","Rating","DidNotEatReasonId","submitRatingMessage","DidNotEatReasons","popoverInfo","trustAsHtml","contentHtml","FlightCrewMeal","hasRegChanged","FlightDeparture","crewMealDetails","getFlightsByFlightId","acTailNo","panelToShow","flightFooter","MemoFactory","ReportGuidFactory","handleIfReport","report","ReportGuid","deleteTempReport","restoreGuid","openReportDialog","gotoFlight","returnTimeDiff","paxTimeDiffInMins","nextFlight","previousFlight","currentFlight","getPreviousAndNextFlights","showAssessment","showFlightReport","LineStatus","hasMultipleReports","departure","openSyncPopover","firstSyncWarning","secondSyncWarning","lastSync","enableSyncPopover","showTimeDiff","reportsPopoverTemplateUrl","gotoFlightInfo","openCabinReport","encodeURIComponent","getLocalFlightFromStorage","serverReportForThisUser","getServerCabinReportForUser","serverReportsByAnotherUser","getServerCabinReportsByAnotherUser","ReportId","openReport","resetDevice","danger","gotoPaxInfo","gotoMemosLibrary","RefreshRoute","showPopover","showMobileMenu","userPosition","openAssessment","gotoTicket","goToSafetyReport","goToFatigueReport","syncWarning","toggleCrewList","relatedTrainees","dynamicSize","CrewMembers","Trainees","groundInfo","printHotelType","HotelType","printContactType","contactType","stations","stationsInfo","filterHotelType","filterContactType","showInfo","station","stationInfo","ActiveHotels","ActiveContacts","ActiveGeneralInfo","contactInfo","ContactTypes","distinct","ContactType","findDistinctContactTypes","hotelInfo","HotelTypes","findDistinctHotelTypes","CabinReportLocalEditCreatorFactory","arrival","isInFinalState","saveNewUsedState","createNewLocalReportForFlight","DepartureGroundServices","saveReport","updateFlightFromReport","setCabinReportToStorage","ArrivalGroundServices","getGroundServicesByStation","checkForNewGroundServices","mainFooter","FaqFactory","RequestFactory","LeaveRequestFactory","PassengerMealServiceFactory","messagesCount","messages","faqs","unreadMessagesCount","newFAQCount","updatedFAQCount","ReadDt","getNotHiddenMemos","memosCount","getFAQsFromStorage","newItems","updatedItems","gotoMemos","gotoLeaveRequests","leaveRequestInformation","getLeaveRequestInformation","openSearchFlightsModal","memosByCategory","MemoImagesFactory","day","filterMemos","distinctMemos","normalizeMemos","getMemosFromStorage","allMemos","distinctMemosAll","getMemoImagesFromStorage","allMemoImages","distinctData","sortData","dynamicSort","imageId","normalizeMemoImages","distinctMemosImagesAll","q","setMemosToStorage","setMemoImagesToStorage","recreateIndexedDB","memo","CategoryId","Category","memoList","LastUpdated","memoDateA","memoDateB","temp","getMemosForCrewRoute","memos","getMemosForGroundDuty","getMemosForFlight","openMemo","saveOneMemoToStorage","markGroundDutiesUnread","reportsPanel","enableWaterUpliftReporting","waterUpliftSupportingAcTypes","defaultCalendarDate","showSafetyReport","assessmentOnly","trimmedFlightDate","goToCampaignsPanel","hash","showReports","getBottomClass","classname","getTextClass","getAssessmentTextClass","getTopClass","hasIcon","isWaterUpliftRequired","assessmentStatus","securitySearch","showSecurityMsg","securitySearchRequired","DepartureUK","DepartureCDG","DepartureCountry","PreviousEU","hasMessage","ssr","ssrCodes","totalPax","startDate","endDate","duration","getZone","classService","zone","Zones","Class","detailedInfo","properties","propertiesArray","htmlPopover","PassengerSummaryC","PassengerSummaryY","property","Total","VIP","UPGD","FQTVGold","FQTVSilver","UMNR","PRM","DEAF","BLND","DPNA","DEP","INAD","MEDA","CBBG","OTH","UndeliveredChargeableSeats","showFQTVGold","showFQTVSilver","showUMNR","showPRM","showDEAF","showBLND","showDPNA","showDEP","showINAD","showMEDA","showCBBG","showOTH","showIrregularites","showVIP","hasZones","zoneC","zoneY","waterQuantity","BookedC","BookedY","asHours","supportsWaterUpliftAcType","UMNRDetails","totalUMNR","row","column","SSR","IsUMNR","updateConfirm","needUpdate","waiting","checkVersionExpiration","prototype","orderByAsc","sortedArray","v","groupByKey","rv","getTimezoneOffset","setHours","_DatetoJSON","toJSON","eventInType","_toConsumableArray","_arrayWithoutHoles","_iterableToArray","_nonIterableSpread","elem","iter","from","arr2","_typeof","isError","TypeError","messageId","trainees","removeAircraftRow","clearDowntimeDuration","downtimeDuration","courses","savedCourses","RangeError","firstDate","secondDate","diffInMins","date1","date2","diffInDays","MinutesToString","hours","mins","AddDays","days","endsWith","suffix","startsWith","str","join","getHash","shaObj","jsSHA","elipsis","faceMasks","FaceMasksFactory","requiredFields","masksForm","Types","Fields","Value","invalidForm","submitMessage","DryStoreFound","Type","DryStoreLeft","UniversalFound","UniversalLeft","FlightMaskReport","submitFaceMaskReport","timestamp","validInput","FaceMasks","initializePanel","submitResponseObj","flightMasks","FAQCategory","FAQSubcategory","Question","Answer","IsNew","WasUpdated","setFAQsToStorage","FAQItem","setFAQsFromServer","newFAQs","oldFAQs","newPairList","oldPairList","Subcategories","k","Pairs","exists","FaqsCtrl","FAQs","openAnswer","pair","FAQItems","updateFAQs","searchText","btnFilter","FAQ","showCategory","Subcategory","showSubCategory","answer","SubcategoryDescription","CategoryDescription","FaqsModalCtrl","aimsCrewMemos","getAimsCrewMemosByDate","Line","getAimsCrewMemosFromStorage","setAimsCrewMemosToStorage","clearAimsCrewMemosFactoryFromStorage","crewMemos","datesMemos","newCrewMemos","aimsCrewMemosLS","cleanOldAimsCrewMemos","PreviousFlightNo","PreviousStation","PreviousETA","PreviousGATE","PreviousSTAND","PreviousSTANDArrival","NextFlightNo","NextStation","NextETD","NextGATE","NextSTAND","NextSTANDArrival","getAircaftPositionsFromStorage","setAircaftPositionsToStorage","clearAircaftPositionsFromStorage","updateAircraftPositionsToStorage","aircraftPositions","previousAircaftPositions","Registration","setAircraftDifferencesToStorage","getAircraftDifferencesFromStorage","clearAircraftDifferencesFromStorage","getAircraftDifferencesByFlightId","difference","newAircraftDifferences","aircraftDifferencesLS","showDefaultView","defaultColumns","timesColumns","commercialColumns","delaysColumns","showFlightTimes","showCommercialView","showDelaysView","showHiddenRows","toggleshowHiddenRows","showDate","acRouteSTD","flightSTD","startOf","openCrewContactsModal","FlightConfigCtrl","ETAdate","STDdate","ETAtimestamp","STDtimestamp","setUTCFullYear","getUTCFullYear","setUTCMonth","getUTCMonth","setUTCDate","getUTCDate","getFlightDelaysFromStorage","setFlightDelaysToStorage","addFlightDelays","newflightDelays","newFLightIds","flightDelaysLS","cleanOldFlightDelays","FlightGateCtrl","FlightGateFactory","distinct_gates","searchFilters","FlightsFilters","gates","getAfterSTDFromStorage","isConnectedFlightClose","connection","connFlightDate","TimeDifference","time","timeString","sign","dayString","ms","daysms","hoursms","substr","IsOld","addFilter","applyFilter","removeFilter","TotalFlights","Dep","connectingTime","STD_lcl","flightGateTime","Codeshares","distinct_gate","Gate","DepGate","Arr","UpdatedDate","lastUpdate","flightArrivalTime","timeDate","newFlightgates","hasGates","FlightGate","STD_Diff","STA_Diff","STA_lcl","ETD_lcl","ETA_lcl","DepStand","previousUpdate","previousGate","previousSTD","previousSTD_lcl","previousSTD_Diff","previousSTA","previousSTA_lcl","previousSTA_Diff","getRoute","dtSTD","dtSTA","dtETD","dtETA","dtSTD_lcl","dtSTA_lcl","dtETD_lcl","dtETA_lcl","timeSTD","timeSTA","timeETD","timeETA","timeSTD_lcl","timeSTA_lcl","timeETD_lcl","timeETA_lcl","hasETD","hasETA","depDelay","arrDelay","setUpdatedNow","gateChanged","stdChanged","staChanged","stdDiffChanged","staDiffChanged","changesToString","getKey","stringIsoToDateTime","dt","year","getFullYear","month","getMonth","stringIsoToDateString","stringIsoToTimeString","self","hour","getHours","getMinutes","getFromStorage","setToStorage","processUpdatedData","listPrevious","flightPrevious","hasChanged","previousLength","dep","flightgates","dateETD","FlightInfoCtrl","enableFaceMasks","crewCheckInStatuses","dutyDate","crewPhoneNumbers","hideSidePanel","shownSideMenu","sideMenuItems","showSidePanel","menuItem","html","goToPanel","isMobile","onlyUnique","labels","mealCdata","mealYdata","SpecialMeals","Count","datasets","fillColor","strokeColor","highlightFill","highlightStroke","phoneNumberInfo","previousDutyInfo","isFlight","arrivalDate","departureDate","showDepartureDate","GroundDutyDate","setMaskPaxInfoInRoute","flightCrewPreviousDuty","cabinCrewPreviousDuty","dhcCrewPreviousDuty","hasPreviousDuties","saEligibility","flightZones","zones","zoneTitles","RenderFlightZones","getMessagesFromIds","openMessage","markReaden","showConnFlights","crewChart","cp","fo","sa","fa","dhcCp","dhcFo","dhcSa","dhcFa","generateCrewChart","MCT","openFlightConfig","selectedItem","openGates","toggleViewMode","not","flightStatus","previousActualTAT","previousEstimatedTAT","previousScheduledTAT","previousDiffWithSceduled","nextActualTAT","nextEstimatedTAT","nextScheduledTAT","nextDiffWithSceduled","objCallBack","Station","getGroundServicesFromStorage","setGroundServicesToStorage","Services","IsDefault","Used","clearGroundServicesFromStorage","servicesLS","passengerEvents","ToolkitFactory","CustomerEventFactory","Passengers","groupFlightCustomerEventsByPassenger","getToolkitItemsFromStorage","toolKitItems","customerEvent","OneStopShopEvents","ToolkitItem","ToolkitItemId","Treatment","TreatmentId","passenger","GivenName","Surname","numberOfEvents","paxNames","SyncPaxCtrl","hideElements","showOnSuccess","showOnEmptyData","showOnSuccessNoFlightData","showOnOutOfDateRange","isFetchingFlightData","flightDataStatus","updateStatusGenerator","newDuty","Error","msg","CabinServiceManagementLists","turnAroundTimes","turnArroundTimesAcTypes","showTaTpanel","supportsTurnArroundTimes","atd","startofTAT","prevATA","lateArrival","scheduledTurnAroundTime","comparedValue","actualTurnAroundTime","AddFlightCtrl","AircraftTypeFactory","doCancel","doAdd","processForm","minSelectableDate","maxSelectableDate","minSelectableDateStr","maxSelectableDateStr","selectedTime","hstep","mstep","ismeridian","hourFormat","datepicker","opened","openDatepicker","createFlightFromUIValues","formData","flightDateStr","flightTimeStr","flightNumber","flightDeparture","flightDestination","flightRegNo","flightAcType","createLocalFlight","formFlight","$valid","newFlight","saveLocalFlight","actypes","getAircraftTypesFromStorage","aircraftTypes","CalendarCtrl","TrainingSessionFactory","ScheduleAcknowledgeFactory","TraineeCoursesDetailsFactory","isAssessmentEnabled","storageUsage","usedSize","addFlight","openSynch","setLastShow","synchresult","pendingOverdueReports","draftReports","completedReports","gotoUnreadMemos","gotoMessages","gotoLeaves","hasUnsetTraining","hasScheduleChanged","acknowledge","showPasswordExpiryAlert","showExpiriesAlertCalendar","showSubmissionDeadlineAlertCalendar","expiryList","submissionDeadline","showCheckInAction","openCheckIn","searchPastGroundDuties","hasManualEntry","gotoGroundDutyInfo","removeManualEntry","removeGroundDuty","daysDiff","hasTraineeCourse","removeFlightTrainingManualEntry","gotoCrewRouteInfo","pastTrainingsViewSummary","viewPastTrainings","removePendingGDEntry","totalIncompleteGD","removePendingFlightEntry","totalIncompleteFlightDuties","passwordExpiry","showAlert","lastChange","daysLeft","groundSessions","flightSessions","isReload","NeedsToSync","leaveRequest","leaveRequestCloseDate","CloseDate","getSubmissionDeadlineDateFromStorage","getUnreadMemos","unreadMemosCount","getFlightsFromStorageAndCheckIfTooOld","getLocalFlightsAndMergeWithServerFlights","needsToSync","getGroundDutiesFromStorage","crewRoutesEvents","routes","crewRouteEvents","second_icon","courseStatuses","trainingStatus","dutyEnd","courseIds","dutyBegin","existingSessions","isBetween","HasLimitedInfo","routeIndicators","RouteIndicators","routeIndicatorCodes","routeIndicatorCode","routeIndicatorColor","formatCrewRoutes","groundDutiesEvents","traineeGroundCourses","groundEvents","RelatedGroundDuties","coursesFlat","relatedTraineeCourse","relatedDutyCourse","existingSession","Unread","formatGroundDuties","getTraineeCourses","showPastTrainingsSummary","manualGroundDuties","getManualGroundDutiesFromStorage","manualDuties","findManualEntries","manualFlightTrainings","findManualFlightTrainingEntries","flightEvents","traineeFlightCourses","third_icon","flightCourseStatuses","flightCoursesFlat","TrainingIndicatorCode","relatedFlightTraineeCourses","IsTrainee","CabinReportStatusWeight","statusWeight","IsScheduleChanged","isScheduleChanged","formatFlights","getFlightCourses","crewHotelsEvents","hotels","endOf","formatHotels","specialDates","scheduleChangedDates","getScheduleChangesFromStorage","findScheduleChangedDates","routeIndicatorLetters","objdate","_d","dayClick","lastLog","canShowSync","isOpenUpdateModal","getMandatoryUnreadMemos","mandatoryUnread","showSubmissionDeadlineAlert","passwordLastChangeDate","lastChangeDate","expirationDate","preparePasswordExpiryData","showScheduleChangesReminder","showScheduleChangesModal","showExpiriesReminder","showSubmissionDeadlineReminder","showSubmissionDeadlineModal","showReminderModal","savedGroundSessions","savedFlightSessions","ServerCabinReportFactory","FlightCrewMemberFactory","liveVersion","Flight","BookedInf","BookedPad","BookedChld","ActualC","ActualY","ActualInf","ActualPad","ActualChld","DepartureICAO","DepartureName","ArrivalICAO","ArrivalCountry","ArrivalName","LineStatusDescr","LocalReportId","ServerReportLink","LocalReportHasNothingToReport","ServerReportHasNothingToReport","IsLocal","DepartureTimezone","ArrivalTimezone","CallSign","getDescription","getSeniorAttendantsCount","initializeCabinReportStatus","getCabinReportStatusDescr","dataIsRecent","storeFlightsWithReportsAndMessages","flightsX","cabinReportsX","messagesX","pr","me","fi","pri","Source","constSourceStoredOwn","constSourceStoredOther","mi","vf","ValidFrom","vt","ValidTo","QueryType","Country","FlightDirection","AirportA","AirportB","datetime","destination","regno","actype","localFlights","flightIndex","serverFlights","reportIndex","allflights","mergeFlightInfo","showPaxNames","currentFlightInfo","ArrivalStand","DepartureSchengen","ArrivalSchengen","ArrivalEU","DepartureCountryISO","ArrivalCountryISO","markScheduleChangedFlights","oldFlights","lastScheduleDate","getLastScheduleDate","initializeFlights","getFlightsWithStoredReport","insertFlightsWithPendingTrainings","flightsWithPendings","flightIdsLS","flightsToInsert","getTheFirstAndTheLastFlightDates","firstFlightDate","lastFlightDate","currentDate","dateString","attendants","hasServerReportForThisUser","hasServerReportsByAnotherUser","NothingToReport","ReportedItems","userAimsId","GenericModalFactory","FlightCrewMember","sex","ReminderModalCtrl","updateShowScheduleChangesModal","updateShowSubmissionDeadlineModal","EventFormModalCtrl","eventType","defaultStart","StartTime","defaultEnd","EndTime","resetStart","formValues","resetEnd","Remarks","getNowValue","currentUtcTime","NotRequired","notRequired","saveEvent","setEventsForFlightId","resultMessage","handleSaveResponse","startGetTime","endGetTime","requiredValueChanged","showTimePickers","showStart","showEnd","showStartToggle","showEndToggle","getEventsNTypes","eventTypes","getEventTypes","getEventsByFlightIdFromLS","EventCode","EventTypeId","refreshEvents","getEvents","openEvent","setEventTypes","objEventType","setEvents","getEventsFromLS","objEventTypeCallback","uri","encodeURI","eventTimesFixed","clone","startDateObj","endDateObj","cleanOldDataServiceEvents","EnableStartTime","EnableEndTime","EnableNotRequired","AllowRemarks","objEvent","objEventCallback","GroomingCategoriesFactory","setGroomingCategories","groomingCategories","getGroomingCategories","collectGroomingReports","groomingReportsByCrew","groomingReports","category","UserInput","groomingCategoryId","feedback","saveGroomingReports","localStorage","setItem","loadGroomingReports","getItem","clearGroomingReportsFromStorage","removeItem","Active","GroomimgCategoriesModalCtrl","crewData","originalCategories","copy","isSaveEnabled","isSelected","toggleCategorySelection","clearInput","gdCrewInfo","grounddutyid","AIMS_ID","GroundDutyCtrl","toggleEditMode","selectTrainee","trainee","Absent","updateGroundDuty","dutyCourses","refreshGroundDuty","DutyId","CourseIds","refreshSuccess","GroundDuty","mergeGroundDutyInfo","updateCrewMemberScopes","instructors","getGroundDutyFromStorage","getGroundDutyActiveCourses","traineesFlat","related","relatedDutyIns","IsInstructor","relatedDutyTr","flatMap","DutyDescription","Instructors","dateDifference","checkDate","setGroundDutiesToStorage","currentGroundDutyInfo","GroundDutyNo","groundDutyCourse","allCoursesAreCompleted","relatedDuty","isLastDay","traineeCodes","Set","remainingTraineeCodes","codes","mergeGroundDutiesToStorage","fromSync","incomingDuty","incomingTraineesFlat","incomingTrainee","existingDuty","existingTraineesFlat","existingTrainee","addGroundDuty","getFirstAndLastDateOfGroundDuties","firstDutyDate","lastDutyDate","SearchPastGDCtrl","PastDutyFactory","isCourseLimited","hasError","closeModal","showMessage","availableCources","pendingDuties","pendingGroundDuties","flightTrainings","pendingRoutes","pendingFlightCourses","flightCourses","flightsForPendingRoutes","pendingRoute","handleFailedResponse","dutyDatePicker","searchGDByDate","getPastDuties","searchNotStarted","getNotStartedDuties","notStartedGroundDuties","groundCourses","handleNotStartedSubmitResponse","searchGD","compileProviderConfig","$compileProvider","aHrefSanitizationWhitelist","exceptionConfig","$provide","decorator","extendExceptionHandler","$delegate","exception","cause","http401interceptor","headers","responseError","rejection","httpCrewTokenInterceptor","$$url","expiresAt","crewToken","expires","httpHeaderInterceptor","aimsIdToString","method","toJson","absolutePath","lastIndexOf","httpProviderConfig","$httpProvider","defaults","useXDomain","common","interceptors","localStorageMD5Config","localStorageMD5ServiceProvider","localStorageServiceProvider","exec","href","setStorageType","setPrefix","setStorageCookie","enableCompression","$injector","$window","lastError","stackTrace","getToken","contentType","errorUrl","beforeSend","setRequestHeader","loggingError","warn","stack","errorDescr","postFilter","annualLeavesSummary","AnnualLeavesFactory","showAnnualLeavesSummary","annualLeavesInfo","getAnnualLeavesToStorage","annualLeaves","groupedLeaves","previousGroup","dates","groupAnnualLeavesByType","setAnnualLeavesToStorage","annualLeavesInInfo","FlexCombination","seasonConfiguration","seasonRequest","sortSetupOrderNo","period","LeaveRequestPrioritySlots","setupOrderNo","MockLeaveRequestPrioritySlots","LeaveRequestPriorityPeriods","temp2","fromJson","sortableOptions","handle","ui","stop","removeSlot","slotIndex","LeaveRequestPrioritySlotsHelper","LeaveRequestCtrl","setupMockLeaveRequestPriorities","priorities","slots","tempOrderNo","findSlot","onSuccessSendRequest","closeDateStr","LeaveRequestInformation","ShowSuccessMessage","ShowErrorMessage","onErrorSendRequest","getRandomBorderColor","season","cssClass","Configuration","getRandomTextColor","IsValidLeaveRequest","LeaveRequest","RequestNoleave","invalidSelectedLeaveDays","LeaveRequestSeasons","LeaveRequestPriorities","HasInvalidPeriod","showHelp","showSuccessLeaveApplicationMessage","getConfigurationDetails","QualificationGroup","RequestLessDays","RequestNoLeave","GroupStatus","YearId","MemberId","seasons","HasSpecificCombinations","SeasonId","StartDate","EndDate","Slots","Configurations","ConfigurationId","mergeRequest","Seasons","leaveRequestSeason","configurationDays","Days","Priority","initializeNewRequest","updateLeaveRequestSeason","Periods","ConfigurationPeriodId","totalDays","hasConfig","LeaveDays","showCombo","radioConfigurationModel","sendRequest","saveLeaveRequest","addComment","leaveRequestApiURL","saveLeaveRequestInformation","cleanRequest","LeaveRequestInstructionsCtrl","normalizePage","page","instructionPages","nextPage","previousPage","SpecificCombinations","seasonRequests","recalculatePriorities","specificCombinations","resetEditablePeriods","isEditable","IsEditEnabled","selectEditablePeriod","selectedSlotTemp","selectedRequestTemp","selectedSlotDaysTemp","updateEditablePeriod","slot","removeSpecificCombination","priority","indexOfRemovedObj","addNewSpecificCombination","newSpecificCombinationPriority","getBorderClass","hasEmptyFields","hasFilledFields","isDisabled","CSSclass","EndDay","StartDay","CabinAPIService","login","bearer","Authorization","LoginCtrl","afterLoginSuccess","isLoggingIn","errorName","afterLoginFinal","afterLoginError","Message","resetUser","isSupported","goSecure","goNormal","moreInfo","toggleMoreInfo","loginFailedAttemps","getLoginFailedAttemps","azlogin","azureADAuth","msalConfig","auth","cacheLocation","storeAuthStateInCookie","myMSALObj","msal","PublicClientApplication","username","handleRedirectPromise","account","currentAccounts","getAllAccounts","selectAccount","hashedPwd","syncDialogLastDt","tokenExtended","aimsid","setUser","setActiveUser","onfinally","newLoginFailedAttemp","failedLoginAttemps","act","extendToken","Token","Promise","silentRequest","scopes","redirectUri","loginRedirect","getAccountByUsername","acquireTokenSilent","tokenResponse","idToken","InteractionRequiredAuthError","acquireTokenRedirect","redirectError","logoutRequest","postLogoutRedirectUri","logoutRedirect","isSynced","LocalId","setAllLuggageComplianceToStorage","getLuggageComplianceByFlightId","getLuggageComplianceFromStorage","getPassengerLuggageCompliance","saveLuggageCompliance","luggageComplianceReport","removeLuggageCompliance","luggageComplianceReportId","saveReportFailedCallBack","LuggageComplianceReports","luggageReports","syncedReport","setLuggageComplianceToStorage","isChecked","saveLuggageComplianceToStorage","updateLuggageCompliance","removePendingsLuggageCompliance","pendingReports","unsyncedReport","removeLuggageComplianceByFlightId","deleteAllLuggageComplianceReportsByFlightId","allReports","removeAllLuggageCompliance","deleteReportsSuccessCallBack","submitLuggageCompliance","postData","ResponseSuccess","syncedReports","syncedReportsFromLS","updateAllPendingsToSynced","unsyncedReports","createdDay","Created","trimmedDay","cleanOldPendingChecks","saveFlightIsCompliantToStorage","IsFlightCompliant","getFlightCompliantStatus","returnStatus","HasPendingsReports","luggageComplianceReports","flightCompliantReport","allLuggageReports","twoLuggageEvents","getLuggageCompliancePassengers","hasSyncedPassengers","flightCompliant","luggageReport","columns","HasTwoLuggage","flightIsCompliantReport","applyAllPassengersAreCompliant","resetAllPendings","cabinLuggageReport","FareFamily","applyFlightComplianceReport","reset","resetSynced","allPassengersAreComplianceConfirmation","CalendarRedirectModalCtrl","MandatoryModalCtrl","gotoMandatoryUnreadMemos","Memos","Memo","addMemoToStorage","ValidateCountryCategory","criteria","isDepartureCategory","isArrivalCategory","Special","Field","FieldOptional","departureField","arrivalField","special","isDeparture","isArrival","getAllUnreadGroundDutyMemos","memosCollection","unreadGroundDutyMemos","MemoCriteria","PassengersHasSsrCode","memoCriterion","PassengerSummaryX","isValidZone","CriteriaZone","FlightZones","IsHidden","clearMemosFromStorage","flightMemos","AcRegistration","RouteStart","RouteEnd","ViceVersa","TrainingIndicatorId","getStoredMemosIds","memoIds","memoIdRead","deleteMemoFromStorage","MemoId","setMemosFromServer","memoIdsToSend","lastSyncDate","IsMemoIncluded","groundDutyMemos","fromDutyDate","toDutyDate","getAllPaxInfoFromStorage","paxInfoResult","inserted","g","Zone","IsMandatory","z","addMemoImageToStorage","MemoImage","MemoImages","saveOneMemoImageToStorage","deleteMemoImageFromStorage","MemoImageId","deleteMemoImageByMemoId","setImagesToServer","images","clearMemoImagesFromStorage","getMemoImagesByIndex","MemoModalCtrl","hasCountry","hasFlightNo","hasAirport","hasRoute","hasAcType","hasZone","hasEuropean","hasSchengen","hasAcRegistration","hasSsrCode","hasTrainingIndicator","hasGroundDuties","hasNone","showImage","Image","write","outerHTML","Body","MemosCtrl","searchResultsCount","searchResults","MemosByCategories","filterList","selectMemoCategory","selected","toggleSidePanel","searchMemos","filteredMemos","newList","diffTime","ceil","showAllCategory","select","active","showhideDescr","toShowBody","toShowAppliesTo","tommorowTimestamp","expired","MessageCtrl","messageCount","isEnable","AuthorName","PositionCP","PositionFA","PositionFO","PositionSA","FeedbackCause","setMessagesToStorage","clearMessagesFromStorage","Ids","selectedMessages","getUnreadMessages","filteredMessages","markReadAsSynched","readMessages","Synched","getUnsynchedReadMessages","filtered","storeMessagesFromServer","MessageModalCtrl","messageBody","Synced","setCustomerEventsToStorage","getCustomerEventsByFlightId","getCustomerEventsFromStorage","getFlightCustomerEvents","updateCustomerEvent","saveCustomerEvent","setCustomerEventToStorage","flightCustomerEvents","oneStopShopPassengers","flightIncidents","incident","NPS","removeCustomerEvent","customerEventId","getUnsyncedCustomerEvents","unsyncedEvents","tempId","TemporaryId","deleteOldCustomerEvents","fromDate","setHistoryEventsToStorage","getHistoryEventsFromStorage","getPassengerHistory","passengerFqtv","Fqtv","passengerUci","FQTVNumber","flightHistoryEvents","history","deleteOldHistoryEvents","historyEvents","setToolkitItemsToStorage","ToolkitItems","addToolkitItemToStorage","saveToolkitItemToStorage","setToolkitItemsFromServer","toolkitItems","PaxCategory","localToolkitItems","isToolkitItemIncluded","PassengerMealsCtrl","selectedService","selectedCycle","filteredMeals","isAllCyclesSelected","areAllMealsOpen","filteredServices","mealServiceSearch","selectService","ServiceCycles","filterByCycle","cycle","Meals","MealName","localeCompare","toggleAllMeals","meal","isInfoVisible","searchMeals","searchTextLower","mealNameMatch","filteredMealItems","MealItems","itemNameMatch","ItemName","allergenMatch","Allergen","compositionMatch","Composition","matchFound","highlight","filterMealServices","passengerMeals","ServiceName","getPassengerMealServicesFromStorage","toggleVisibility","setPassengerMealsServicesToStorage","getPassengerMealServiceFromStorage","serviceId","checkAndsetPassengerMealsServicesToStorage","validResults","CreatedDate","storedLatestService","latest","firstNewService","PassengerCtrl","WifiVouchersFactory","WifiAvailabilityFactory","ReportIsFinal","ugradePassenger","showUpgradeInput","showUpgradeWarning","showUpgradeError","showSuccess","upgradedSeatNo","successMessage","upgradeRemarks","submitUpgrade","missingZeroes","formatSeatInput","IsEmptySeat","showSeatChangeError","isSeatAvailableForUpgrate","saveUpgrade","undo","UpgradedPassengers","OriginalSeatNo","UpgradedToSeat","wifiAvailability","getRegistrationsFromStorage","supportsWifi","registrations","retrieveWifiVouchers","RequestWifiVouchers","STDLocal","newVoucherCode","retrieveHandleSubmitResponse","notRetrieved","createTextVoucher","RequestCreateVoucher","FlightNumber","FullName","PlanId","createWifiVoucher","createHandleSubmitResponse","createStreamVoucher","params","ChangedSeat","IsSeatChanged","changeSeatFormData","changedSeatNo","seatChangeRemarks","showSeatChangeInput","showSeatChangeWarning","showSeatChangeSuccess","successSeatChangeMessage","submitSeatChange","IsAlreadyGivenSeat","isSeatAvailableForChange","saveSeatChange","undoSeatChange","ChangedSeats","closeChangeWarning","linkedPassengersGroup","isFeedbackUpdated","submitCampaignFeedback","Campaign","hideFooter","showOneStopShop","toggleFooter","treatmentAvailability","counter","ossCounter","updateCabinLuggageReport","luggageCompliance","hasTwoLuggage","upgradedPassenger","UpgradedSeatNo","updateReport","newSeatNo","NewSeatNo","changedSeat","updateReportForSeatChange","textAndSurfCodes","streamCodes","newVouchers","wifiVouchersCodes","VoucherCode","LinkedPassengers","LinkedPassengersWithProductId","ProductId","getlinkedPassengers","PaxCtrl","showMobileMenuFilters","filterPax","viewMode","mode","showPaxName","showDetails","showConnections","showMeals","filterRow","filterPaxC","filterPaxY","filterAdults","filterChildren","filterInfants","filterUMs","filterFqtv","filterConnections","filterSpecialMeals","filterFqtvSilver","filterFqtvGold","filterWheelchair","filterAssistance","filterDeportees","filterDHC","filterVIP","filterChargeableSeats","filterEligibleForUpgrade","filterSeatChanges","filterIrregularities","filterCampaigns","multiSelect","passengerName","filterCol","howClose","openPassenger","inputObject","SeatMode","attachCampaign","CampaignCounters","pending","completed","col","attachLuggageCompliance","isMultiSelected","multiSelectCount","resetFilters","initializeFilters","initializeViewMode","applyLuggageCompliance","opcc","modalInstance","specialMeals","luggageComplianceConfirmation","toggleFlightInfoView","Cabin","InfantName","Connection","SpecialMeal","SpecialMealB","TierLevel","IsGroupPRM","IsDEAF","IsBLND","IsDPNA","IsINAD","IsGroupDEP","IsVIP","IsCHU","IsCHX","IsEligibleForUpgrade","UndeliveredChargeableSeat","campaignInfo","opccReport","upgradedPassengers","setUpgradedSeatsFromReport","changedSeats","setChangedSeatsFromReport","changedSeatsNo","connectingPax","ConnectingFlights","ConnectingFlightId","lsPaxInfo","setPaxInfoToStorage","oldDraftPaxInfo","paxInfoFlightIds","Statistics","GetStatistics","newListPaxInfo","intFlightId","updatePaxInfo","cleanOldDataPaxInfo","applyMask","lastFlight","maskedPaxFlightList","maskPaxNames","otherPaxInfo","setMaskPaxInfoToStorage","cabinType","curtainRows","DHC","RowNo","InfantSurname","InfantGivenName","toolkit","passengerCategories","none","gold","business","silver","blue","economy","setupToolkit","paxCategories","passengerClass","Carrier","TierDescription","getPaxCategories","matchingCategories","TouchpointCategories","treatmentGroups","initializeToolkit","CustomerEvent","getCustomerEvents","isListView","isEdit","addEditIncident","toolkitOptions","Fallback","newForm","selectedIncident","selectedTreatment","passengerEmail","contactLanguage","telephoneCode","passengerMobile","CrewComments","TelephoneCode","Mobile","ContactLanguage","goBack","isIncidentUpdated","deleteAlert","closeAlert","isRedeemed","getIsRedeemed","isRedeem","IsRedeemed","submitCustomerEvent","FQTVTierLevel","ClassOfService","toggleDeleteAlert","validForm","form","emailFormat","mobileFormat","philoxeniaQuestions","PhiloxeniaQuestionsFactory","flightQuestions","hasPhiloxeniaData","philoxeniaData","getFlightPhiloxeniaQuestionsFromStorage","Questions","RepliesCounter","ratingQuestions","Option","OptionText","Counter","Percentage","getPhiloxeniaQuestionsFromStorage","setPhiloxeniaQuestionsToStorage","updatePhiloxeniaQuestionsToStorage","storedPhiloxeniaQuestionsFiltered","QuestionInfo","optionList","option","currentAnswer","AnswerCounters","OptionId","OptionList","weight","TextValue","AVG","selectedOptionIds","optionsZeroCounterMapper","Options","storedPhiloxeniaQuestions","previousPhiloxeniaQuestions","CCMSFactory","BarTrolleyFactory","AuthorId","ActiveVariousIssues","WarningVariousIssues","CCMSCrewPositionsIsValid","CCMSCrewPositionsErrorMessage","FlightReportSubmittedBy1L","CrewRemarks","ItemsFoundDescription","ItemsFoundAgent","ItemsFoundSignature","ItemsFoundSectionHasValue","ItemsFoundSectionIsValid","UMNumber","UMDescription","UMAgent","UMSignature","UMSectionHasValue","UMSectionIsValid","WaterUpliftSuggestedQuantity","WaterUpliftInitial","WaterUpliftRemarks","WaterSectionHasValue","WaterSectionIsValid","GroundServicesSectionHasValue","BarTrolleys","BarTrolleysIsValid","FirstAidKits","FirstAidKitsIsValid","MedicalIncidents","MedicalIncidentsIsValid","SpecialMealIssues","SpecialMealIssuesIsValid","Supplies","SuppliesIsValid","SuppliesErrorMessage","TravelValueSeals","TravelValueSealsIsValid","TravelValueIncomplete","TravelValueIncompleteRow","TravelValueIncompleteReason","TravelValueRemarks","VariousIssues","updateTotals","validateCCMS","getCCMSObj","saveReportAsTemp","getRemaining","IncompleteServices","IncompleteServicesIsValid","BoardingTimesRemarks","FirstPaxTime","LastPaxTime","showBarTrolleyUploadImage","showBarTrolleyInsertData","disableBarTrolleysPhotoRemarks","LuggageNumber","LuggageDescription","GroomingReports","allActiveVariousIssues","allWarningVariousIssues","variousItemCount","ItemHasValue","LuggageSectionIsValid","LuggageSectionHasValue","Photos","photos","photosCount","showOrHideBarTrolleyInputs","FAKUsed","Symptoms","DoctorInvolved","MealType","SupplyType","TravelValueIncompleteIsValid","TravelValueIncompleteErrorMessage","ServiceClass","FromRowNo","ToRowNo","ServiceType","Reason","valuesInError","allCCMSPositions","getCCMSFromStorage","multiplePositionsInError","ccmsObj_i","ccmsPositionsIsValid","ccms_i","ccms","Multiple","ccmsObj_j","ccms_j","multiplePositionError","pos","AcTypeIsValid","ccmsObj","Aircraft","Positions","setCabinReportsToStorage","depStorageGroundServices","found","getCabinReportLocalEdit","reportGuid","getPreviousCabinReportCcmsPositions","acNo","flightDateUTC","flightTimeUTC","previousCcms","flightDateMatch","flightDateCheck","previousRep","deleteReport","cabinReportLocalEdit","getCabinReportLocalEditCountThatNeedToBeSynched","IsExistForRouteDutyDate","getCabinReportLocalEditThatNeedToBeSynched","getNewReport","markReportAsSynched","getFlightIdsWithPendingReports","getGroomingReports","groomingReport","CabinReportTemplateItemFactory","CCMSCrewPositionFactory","existingReport","newReportGuid","getNextGuid","reportTemplateItems","getCabinReportTemplateItemsFromStorage","newReport","crewPosition","HasCrewComments","CabinReportRestoreFactory","IdxType","getReportsFromIdx","addReportToIdx","Report","deleteReportFromIdx","getReportsFromLs","getReportsFromIdxDeleteStoredReports","reportsIdx","storedReportsLs","setReportsToIdx","Reports","updateReportToIdx","clearReportsFromIdx","backUpReports","reportsAll","reportLs","restoreReports","extendReport","CabinReportSendToServer","AuthorCrewId","AuthorCrewAimsId","ActualPassengerC","ActualPassengerY","CabinReportSendToServerItem","TemplateItemId","getReportFromCabinReportLocalEdit","stripIds","DisembarkationTimeRemarks","DisembarkationTimesRemarks","FirstPaxDisembarkationTime","LastPaxDisembarkationTime","itemCount","newItem","inputArray","getCompletedListFromCabinReportLocalEdits","fixUsedValueLS","CabinReportSyncResultFactory","Result","getSyncResult","getCabinReportSyncResultsFromStorage","setCabinReportSyncResultsToStorage","cabinReportSyncResults","Hint","CategoryLabel","PresetComments","setCabinReportTemplateItemsToStorage","cabinReportTemplateItems","ReportCtrl","WaterUpliftActionFactory","FirstAidKitFactory","MedicalIncidentFactory","SpecialMealIssueFactory","IncompleteServicesIssueFactory","SupplyFactory","TravelValueSealFactory","TravelValueIncompleteReasonFactory","customerIncidentQuestionIds","reportId","IsCustomerIncident","hasGroomingCategories","newLocalReport","countDHC","crewNeedsAdditionalFeedback","crewMemberNeedsAdditionalFeedback","crewNeedsAdditionalFeedbackFlatten","AdditionalFeedback","AdditionalFeedbackId","FeedbackAuthorName","schedullDepartureTimestamp","isFuture","showCompleted","panels","bars","visible","medical","security","supplies","travel","um","various","water","upgd","incompleteServices","BoardingTimes","luggage","leg","compressedMode","showAll","boardingTimes","disembarkationTimes","showOnlyOne","panelClicked","currentTarget","parent","dateObj","waterSectionRequired","clearField","fieldName","ok","reportItemValueChanged","openBarTrolleyModal","bart","isInsertMode","openCCMSCrewPositionModal","errorField","openFirstAidKitModal","fak","IsEMK","openMedicalIncidentModal","med","userAgent","match","marginTop","scrollTop","bottom","top","documentElement","offsetHeight","clientHeight","openSpecialMealIssueModal","smi","openSupplyModal","sup","checkEligibleUpgrades","eligiblePassengers","alreadyUpgraded","openUPGDModal","openChangeSeatModal","openTravelValueSealModal","tvs","openIncompleteServiceModal","fleetId","Fleet","openAdditionalFeedbackModal","PhotoData","clearItemsFoundDescription","clearItemsFoundAgent","clearItemsFoundSignature","clearUMDescription","clearUMAgent","clearUMSignature","clearWaterRemarks","clearTravelValueRemarks","clearBoardingTimesRemarks","clearDisembarkationTimesRemarks","clearCrewRemarks","clearVariousItemRemarks","clearBarSealsPhotoRemarks","clearLuggageDescription","cancelClicked","deleteReportClicked","reportChanged","reportTravelValueIncompleteReasons","getReasonsFromStorage","plusTravelValueIncompleteRow","minusTravelValueIncompleteRow","reportTravelIncompleteChanged","TravelIncomplete","plusUMNumber","minusUMNumber","clearUMNumber","waterUpliftActions","getWaterUpliftActionsFromStorageAsStrings","copyCcmsPositions","no","yes","posX","posI","ac","tm","copyCcmsPositionsFinal","reportCCMSPositions","addNewBarTrolley","editBarTrolley","deleteBarTrolley","plusLuggageNumber","minusLuggageNumber","clearLuggageNumber","addNewCCMSCrewPosition","editCCMSCrewPosition","deleteCCMSCrewPosition","showFeedback","toggleAdditionalFeedback","$index","showCrewComments","showAdditionalFeedback","HasAdditionalFeedbackComments","openFlightDetailModal","fd","addNewFirstAidKit","editFirstAidKit","deleteFirstAidKit","addNewMedicalIncident","editMedicalIncident","deleteMedicalIncident","addNewSpecialMealIssue","editSpecialMealIssue","deleteSpecialMealIssue","addNewSupply","editSupply","deleteSupply","addNewUPGD","editUPGD","deleteUPGD","addNewChangedSeat","editChangedSeat","deleteChangedSeat","addNewTravelValueSeal","editTravelValueSeal","deleteTravelValueSeal","addIncompleteService","editIncompleteService","deleteIncompleteService","attachPhotoOnVariousItem","openItemPhotosModal","attachPhotoOnBarTrolley","addNewEMKFirstAidKit","addAdditionalFeedback","openGroomingForm","groomingData","allPassengers","hasFirstTime","BoardingDisembarkationTimes","hasLastTime","firstPaxGetTimeUTC","lastPaxGetTimeUTC","FirstPaxGetTimeUTC","LastPaxGetTimeUTC","firstPaxTimeChanged","hasFirstDisembarkationTime","lastPaxTimeChanged","hasLastDisembarkationTime","firstPaxGetDisembarkationTimeUTC","lastPaxGetDisembarkationTimeUTC","FirstPaxGetDisembarkationTimeUTC","LastPaxGetDisembarkationTimeUTC","firstPaxDisembarkationTimeChanged","lastPaxDisembarkationTimeChanged","autoAdjustTarget","autoAdjustTimer","autoAdjustElement","autoAdjustRun","adjustTextarea","$event","clearTimeout","BarSealsImage","BarSealsImageRemarks","Guid","toObjectList","guidList","getReportGuidsFromStorage","reportGuids","setReportGuidsToStorage","validGuidIndex","resultingGuid","repGuid","getRemainingReportGuids","ReportsHistoryCtrl","ReportsHistoryFactory","reportType","fetchReports","getReportsHistory","contentToShow","showError","handleResponse","checkConnectionStatus","ImageData","imageData","closeImage","getResponse","getCreateRequestResponse","getResponseFailed","setSubmissionDeadlineDateToStorage","submissionEndDate","getActiveRequests","getAncillaries","sendFlightRequest","rosterRequest","requestTimesFixed","afterTime","beforeTime","rosterRequestsURL","sendShiftRequest","sendOvernightRequest","sendOtherRequest","sendGroundRequest","deleteFlightRequest","requestId","deleteRequestsURL","deleteShiftRequest","deleteOvernightRequest","deleteOtherRequest","deleteGroundRequest","getPastRequests","RequestInstructionsCtrl","requestItem","requestType","rejectReason","refreshRequests","isHistoryView","handleDeleteResponse","contents","handleErrorResponse","showPendingIcon","showAcceptedIcon","showRejectedIcon","showFullRequestComment","showFullRejectComment","infoMessage","confirmCancelRequest","toggleFullRejectCommentVisibility","todayDate","FlightDescription","FlightDutyCategory","AfterTime","BeforeTime","StatusText","RequestsCtrl","activeRequests","instruction","QualificationGroupInstruction","showActiveRequests","FlightRequests","GroundDutyRequests","OtherRequests","OvernightsRequests","ShiftTimeRequests","ancillaries","hasDutyPreferencesSettings","hasOtherRequestsSettings","HasOtherRequestsSettings","hasFlightRequestsByFlightNoSettings","HasFlightRequestsByFlightNoSettings","hasFlightRequestsByTimeRangesSettings","HasFlightRequestsByTimeRangesSettings","flightOrDutyPreferenceIsVisible","FlightDutyCategories","isAvailableFeature","DutyCodes","hasAncillaries","singleDate","RosterPeriodFrom","dateFrom","dateTo","RosterPeriodTo","dutyDateFrom","dutyDateTo","optionsSingle","initDate","optionsFrom","optionsTo","optionsDutyDateTo","flightCategoryTypes","Text","isOverlappingDuty","periodNotFound","forceSubmitRequest","closeForm","clearForms","singleDayRequestType","submitLoader","disableSubmit","rosterPeriodFrom","rosterPeriodTo","limitationReached","maxLimit","isOverdue","hasDailyLimitation","weekendRequestsLimitReached","submitForcedRequest","IsForced","openRequest","dutyCode","submitRequest","flightRequestType","ReasonId","requestReason","flightNo","FlightDutyCategoryId","flightDuty","trimmedFrom","trimmedTo","Limitation","DutyDateFrom","DutyDateTo","DateFrom","DateTo","ShiftTimeId","shiftTime","Minimum","minOvernight","Maximum","maxOvernight","RequestFreeText","otherComments","updateFromValue","setFlightRequestType","toggleGroundRequestType","groundRequestType","updateFromValueGD","limitation","pastRequests","showPastRequests","filterRequest","FinalAccepted","ValidationStatusText","getRequestBorderStyle","getRejectReason","rejectReasonId","reasonText","RejectReasons","FatigueCtrl","SafetyReportFactory","confirmCreateFatigueReport","saveFatigueReport","alertStyle","responseMessage","operationalPhasesOptions","rateFeltOptions","signsPhysicalOptions","signsCognitiveOptions","signsEmotionalOptions","counterMeasuresOptions","hours24Options","_","hoursAwakeOptions","flightDep","flightArr","flightRegistration","occurenceTitle","operationalPhase","rateFelt","signsPhysical","signsCognitive","signsEmotional","hours24","hoursAwake","rateFeltSecond","counterMeasures","toggleSelection","signs","idx","getSelectedOptionsText","isRequiredFieldEmpty","sizeLimitKb","fileTooLargeMsg","fileUploaded","fileResult","uploadedFile","fileBlobb","attachedFiles","showMaxFiles","removeFile","attachedFile","arrayLenght","showMaxImages","appendPhoto","isIFileTooLarge","isLarge","submitFatigueReport","fatigueReport","sendFatigueReport","emailFatigueReport","SafetyCtrl","operationalPhases","isFileTooLarge","selectedPhase","isConfidential","submitForm","formCabinReport","saveSafetyReport","getFatigueResponse","safetyReport","aqdBaseURL","AcknowledgeModalCtrl","ConfirmAcknowledge","acknowledgeChanges","Results","setAllScheduleChangesToStorage","scheduleChanges","dateList","dateS","stringToDate","fistChange","hasScheduleChanges","datesToAcknowledge","DatesWithChanges","updateScheduleChangesCallBack","acknowledgeFailedCallBack","SearchFlightsCtrl","SearchFlightsFactory","flightFound","searchFlights","searchCriteria","validationFormError","getFlights","flightsFound","searchCriteriaContent","gotoSelectedFlightInfo","hasPublishedRoster","flightDatePicker","groundDutyDates","flightDates","updateSearchCriteriaScope","getFlightInfo","SelectedFlightCtrl","flightInfoObj","ARR","DEPSTAND","ARRSTAND","BOOKED_C","BOOKED_Y","TotalDelay","UnJustified","DC93","DC9","AircaftPositions","updateFlightInfoScopes","pilotCrewMembers","CrewInfo","PositionCode","cabinCrewMembers","dhcCrewMembers","formattedwaterQuantity","getWaterQuantity","hasFlightInfo","register","reg","refreshing","postMessage","phase","traineeSession","syllabusGroups","traineeSessionItems","Syllabus","ActiveVersion","SyllabusItems","syllabusItem","Tries","Selected","relatedSessionItem","Items","SyllabusItemId","hasRemarks","TryGrading","Competences","attempt","historyTriesCount","newTriesCount","isReadOnly","TriesPerformedCount","completedItem","MandatoryCount","PanelClass","setPanelStyleByProgress","Mandatory","setPanelStyleBySelected","ItemsGrouped","SelectedGroup","syllabusGroup","TraineeCourseCtrl","traineeCourseId","initPhaseDetails","phaseId","courseDetails","CoursePhases","traineePhase","traineeCourse","Phases","PhaseId","selectedTraineePhase","traineeInstructions","TraineeInstructions","examinerInstructions","ExaminerInstructions","flatSullabusItems","Sessions","flatItem","createFlatHistorySullabusItem","flatCourseSullabusItems","syllabusItemHistory","ItemId","courseDate","isTraineeView","setSelectedPhase","showWarning","getTraineeCourse","StatusClass","PhaseStatus","TextClass","BtnClass","sessionTrainee","hasDayGrading","DayGrading","GradeType","Grade","hasReleaseGrading","ReleaseGrading","AcTypes","Sectors","ses","SectorsByAcType","acType","group","Session","Released","ModuleType","NeedsAdditionalTraining","AdditionalTrainingRemarks","CompleteAdditionalTraining","hasSelectedPhase","phases","getSelectedPhase","traineeCoursesDetails","goToTraineeCourse","goToTraineeFlightCourse","HasTraineeView","traineeCourses","getTraineeGroundCourses","getTraineeFlightCourses","objCallbackGround","objCallbackFlights","objTypeGround","objTypeFlight","setTraineeCoursesToStorage","listOfValues","traineeCoursesPerDuty","updateTraineeCourseCallBack","traineeCourseFailedCallBack","setTraineeFlightCoursesToStorage","SyncAPIService","FlightCourses","newDutyInfo","imageStr","From","To","dataStatus","crewRouteStatuses","updateStatusSetter","AircraftPositions","ShowPaxNames","updateCabinReportLocalEditFromSynch","PhiloxeniaQuestions","CabinReportSendToServerFactory","ACSupplyFactory","SpecialMealSourceFactory","SpecialMealTypeFactory","IncompleteServicesSourceFactory","relativeFlightMatcher","oldflight","relativeFlights","oldFlightNo","lastDigit","doSync","allSavedReports","messagesToSend","reportsToSend","passengersCampaignsToSend","phoneCallLog","CrewCallReports","oneStopShopEvents","syncData","SyncCabinReports","Messages","Assessments","PassengersCampaigns","CrewCallLog","LastSyncDate","SyncCabinData","orgFlights","ScheduleChanges","oneStopShop","CustomerEventsSynced","localCustomerEvent","SaveSuccess","rawTrainingCourses","setCoursesFromServer","oldAssessments","CrewRoutes","CateringCrewMeals","CrewHotels","CrewCheckInInfo","FlightServiceEventTypes","AnnualLeaves","CrewExpiries","setRegistrationsToStorage","RegistrationsWithWifi","GroomingCategories","RosterRequestAncillaries","SubmissionEndDate","serverMemoIds","Images","flightData","assessmentTemplate","guids","cabinReportTemplate","setAircraftTypesToStorage","wuas","setWaterUpliftActionsToStorage","acSupplies","setACSuppliesToStorage","specialMealSources","setSpecialMealSourcesToStorage","specialMealTypes","setSpecialMealTypesToStorage","FAQPairs","travelReasons","travelValueIncompleteReasons","setReasonsToStorage","incompleteInFlightServiceListOfValues","setIncompleteInFlightServiceListOfValues","setSyncLog","setCCMSToStorage","TraineeCourses","TraineeFlightCourses","reportResults","syncResult","assessmentResults","verifyFlightAimsIds","verifyFlightIds","missingIds","missingAimsIds","m","o","assessmentsToCreate","finalAssessments","oldAssessment","IsAssessmentExists","newAssessments","manualCCMSCrewPositions","newCCMSCrewPositions","changeStatus","SynchCtrl","reportstobesynched","isSA","syncResultsVisible","isSynching","syncTableData","IsSA","isFirstSync","isTooOldSync","syncVersion","reportCredits","number_of_reports_to_sync","syncAssessmentTableData","number_of_assessments_to_sync","doSynch","showReportSyncResults","showAssessmentSyncResults","syncResultsTableData","syncSuccesses","syncFailures","reports_to_sync","sync_successes_descr","sync_failures_descr","unreadMessages","syncAssessmentResultsTableData","syncAssessmentSuccesses","syncAssessmentFailures","assessments_to_sync","sync_assessment_successes_descr","sync_assessment_failures_descr","syncResultsOk","showSynchError","SyncLog","lastShow","can","newLog","syncLog","clearSyncLog","setLastScheduleDate","TicketCtrl","PhotoFactory","TicketAPIService","ticket","maximumAttatchedPhotos","photo","imageTooLargeMsg","gotoHome","restoreReportsAction","restoreResults","bootboxMessage","sendTicket","validateTicket","imageUploaded","isImageTooLarge","FileType","removePhoto","Version","isLogged","DeviceData","sizeActual","getStoredValues","TicketModalCtrl","competence","hasSelectedSubCompetence","SubCompetences","leftScroll","querySelector","scrollLeft","rightScroll","selectedTraineeSession","showSession","selectedTraineeBadge","selectedAbsentTraineeSession","TraineesSessions","grading","showRemarks","oneAtATime","filterItems","showItem","toggleItems","SyllabusProgress","setPanelStyle","nonCompetentItem","IsGradable","gradingType","selectedTry","invalidItem","outcomeType","traineeSelectedTries","firstTry","additionalTraining","yesAdditional","selectedTrainee","UnderAdditionalTraining","startAdditional","remarksSelection","noAdditional","AdditionalTrainingStatus","clearAdditionalNotes","completeAdditional","continueAdditional","filterTrainee","showTrainee","initializeAdditional","toggleAdditional","openAdditionalModal","userInput","startAdd","AdditionalTrainingModalCtrl","certificateExam","collapseAll","validateTrainee","getRemainingCharacters","gradeUp","isCertificateValid","gradeMax","gradeDown","isExamValid","gradeMin","dutyCourse","isGround","gradeBase","CertificateGradeBase","validateGrading","CertificateOutcome","calculateOutcome","updateSession","isAllOpen","gradingStatus","sessions","EligibilityStatus","CompetenceModalCtrl","Grading","competences","gradingSelection","validateTraineeCompetences","missingGrading","missingPerformanceIndicators","hasMandatory","sub","isCompetenceValid","manageCompetenceGrading","hadMandatory","hadOptional","hasOptional","MandatorySub","OptionalSub","showComments","GradingMessage","GradeA","GradeB","GradeC","GradeD","GradeE","selectSubCompetence","openGradingModal","courseFooter","gotoGroundDuty","gotoCrewRoute","trainingFlightIds","TrainingFlightIds","Media","setReleaseStatus","ShowReleaseWarning","AvailableRelease","checkReleaseAvailability","requiresTraineeSignature","endOfSessionSignature","TraineeSignature","endOfModuleSignature","ReleasedPhase","RequiresTraineeSignature","Authorized","allSignaturesComplete","someSignaturesComplete","MinDays","MinSectors","phaseInfo","completedDays","completedSectors","pastSession","CompletedDays","CompletedSectors","AircraftTypes","visitedAircrafts","AircraftTypesVisited","inputAircrafts","pendingAircrafts","pairPendingAircrafts","pendingArviList","arvi","showReleaseWarning","mergeSyllabusItemWithSession","sessionItem","RepeatRequired","deepCopy","originalObject","setTraineeCompetences","traineeCompetences","traineeCompetence","existingCompetence","commonSub","setSubCompetenceValues","updated","first","last","manageSubmission","sessionSectors","sector","PM","PF","SessionSectorSeats","submittedSession","SessionDate","GroundDutyIds","AircraftVisits","SelectedMedia","SyntheticDeviceId","selectedDevice","selection","ReleaseGradeType","TraineeSessions","SyllabusVersionId","DowntimeDuration","radioValue","PrepareSessionForSubmission","requiresInstructorSignature","syllabusSignature","SignatureRequired","selectedItems","traineeSelectedItems","syllabusItemSignature","InstructorSignature","RequiresInstructorSignature","confirmationMsg","ConfirmationMessage","releaseGrading","needsAdditionalTraining","submitSession","SaveSession","isReleased","syllabusItems","performedTries","mandatoryCount","password","withRelease","SignaturePassword","syllabusPending","syllabus","isSyllabusGradingValid","gradableSyllabusItems","gradableSyllabusItemIds","invalidItems","invalidGrading","invalidCompetences","SyllabusValidationErrors","updateTraineeSignatures","validateTraineeForm","border","scrollToTop","traineeDetailsMsg","InFlight","SyllabusErrors","isDayGradingValid","isReleaseGradingValid","isCertificateGradingValid","isDayCompetencesValid","isReleaseCompetencesValid","isGradeValid","gradingValidationInfo","isTraineeGradingValid","availableCourseInfo","oneTraineeAtATime","allAbsent","SubmitSession","dateAllowed","trainingDay","traineesPending","hasNoAircraft","hasNoDevice","isGradingValid","invalidTrainees","isValidForm","getSessionTrainees","scrollTo","reloadReleasePanel","reloadRelease","showReleasePanel","availableCourse","isCheck","traineeSyllabi","TraineeIds","filterSelectedSyllabus","filterPresentTrainees","selectedPhaseIndex","CrewCoursePhases","releaseTrainee","crewIds","showReleaseBtn","showGroupReleaseBtn","releaseGroup","openTraineeSignature","signatureSuccess","resetSignature","getTraineeClass","textClass","allSyllabusCompleted","validSyllabusGrading","isReleaseSelected","toggleBtn","setAdditionalTrainingDetails","hasLowDayGrading","traineeHasLowGrading","hasDayNumericGrading","hasDayOutcomeGrading","hasDayCompetences","hasLowSyllabusGrading","traineeHasLowSyllabusGrading","EnableAdditionalTraining","AvailableAdditionalTraining","reloadFooter","dayCompetences","MandatorySubCompetences","OptionalSubCompetences","releaseCompetences","traineeSyllabus","historyTries","History","itemsHistory","allHistoryTries","historyTry","performedTry","ActionNo","InstructorName","SubmissionDate","pendingTriesLeft","pendingTries","isFirstTry","DefaultGrade","tries","sessionTries","tryItem","relatedSessionTry","extraTries","existingItem","SyllabusGrouping","setSyllabus","setTraineeSessions","getCourseFromStorage","getCoursesFromStorage","errorOnSaveCallback","localCourse","saveOneCourseToStorage","addCourseToStorage","setCoursesToStorage","Course","localCourses","IsCourseIncluded","updateCourseInfo","errorOnNetwork","traingingApiURL","FetchedTime","FetchedDutyCodes","LastFetchedDutyId","updateFlightCourseInfo","FetchedCrewRoute","getCoursesFromStorageByIds","selectedResults","setCourseOutdated","NeedsRefresh","FlightCourseCtrl","gotoCourse","stickySelectedTrainee","toggleView","refreshCourse","refreshErrorMsg","initCourse","courseTrainees","viewFromFlight","getCrewRouteFlightTrainees","savedCourse","afterRefresh","getSession","CourseTrainees","SequenceWarning","isCourseComplete","needsSubmit","fetched","HasLimitedSession","isCourseOutdated","hasAdditionalTrainingRequest","SubmittedSessions","isUnderAdditionalTraining","headerMsg","hasPendingTraining","hasNotifications","manageCourseStatus","addSessionToStorage","saveSessionToStorage","SessionId","SessionComments","InstructorAimsId","mergeSyllabusWithHistory","_course$CourseTrainee","traineeEligibility","TraineeEligibilty","inactiveTrainees","eligibleTraineeIds","eligibleTrainees","crewCoursePhaseDutyNos","crewrouteTrainingIndicators","coursePhase","FlightTrainingIndicators","relatedDutyNos","relatedPhases","fti","firstPhase","RepeatRequestedItems","createNewPhaseTrainees","nonEligibleTrainees","NonEligibleTrainees","EligibilityDesc","filterTraineesByEligibility","calculatePhaseStatus","ActivePhaseStatus","Selectable","invalidPhaseTrainee","PilotFunctions","mergeCourseWithSession","setSession","localSession","isNewSession","commentInput","filterValidTrainees","saveComment","isDayGrading","hasCertificateExam","GroundCourseCtrl","applyAttendanceFromGroundDuty","availableRelease","tr","HasDayGrading","HasReleaseGrading","instructions","warningMessageText","viewModuleHistory","isParallel","currentActiveOrderNo","SequentialWarning","oldSessions","historyPhase","hasHistory","furtherAheadPhases","isInstructorView","traineesAimsIds","isInstructorOpen","isTraineeOpen","continueSubmission","cancelSubmission","media","isObjectEmpty","filterSyntheticDevices","trainingCenterId","AllSyntheticDevices","SyntheticDevices","device","TrainingCenterId","defaultDevice","addAircraftRow","selectedAircraft","aircraft","acIndex","showDowntimeDuration","showDowntime","sessionDuration","downtimeDurationValueChanged","InSimulator","InAircraft","InClassroom","TrainingCenters","defaultCenter","selectedTrainingCenter","initializeMedia","ModuleHistoryCtrl","selectedSession","historyTrainee","selectedSubmittedSessionBadge","sessionId","initHistory","HistoryPhase","historyTrainees","hasSectors","sectorSummary","totalSectors","allAcTypes","sectors","sectorGroup","SectorSummary","TotalSectors","setTraineeSummary","setHistoryTrainees","traineeSessionId","categories","dutyTrainees","allEligibilityTrainees","dutyTrainee","courseTrainee","allCategory","categorizeTrainee","NotificationModalCtrl","notifications","showHistory","filterSession","showSessionTrainees","selectedSubmittedSession","selectSession","historyAvailable","additionalTrainingRequested","underAdditionalTraining","showReleaseOption","submittedDay","NeedsAdditionalRequest","IsReleased","releasableModule","Submit","RadioModel","TraineeName","submitRelease","SubmitRelease","toggleTrainee","selectedCrewId","submittedSessions","releaseSession","CouldBeReleased","IsStoppedTraineeCourse","AllVisitedAcTypes","initializeTrainees","filterSelectedTrainee","warningTrainees","ReleaseSignatureModalCtrl","signaturePassword","responseTraineeCrewIds","traineeInfo","isConfirmed","confirmAircraft","aircraftVisits","requiredSignature","finalPendigArVis","released","pendingVisits","maxLength","maxList","hasPendingAircraftVisits","SignatureModalCtrl","confirmSubmit","releaseWarning","isGroundDuty","releaseSubmit","withGrading","allAvailable","notReleased","itemSelection","selectTry","pendingAttempt","selectGrading","triggerSyllabusClick","el","getElementById","triggerHandler","updateTraineesSyllabus","updateTry","itemAutoSelection","hasCompetencesGrading","itemTry","tryCompetenceGrading","mandatoryTries","competentCount","nonCompetentCount","isCompetent","updatePersonalizeRemarks","traineesPersonalizedRemarks","personalizedRemark","syllabusItemId","remarks","addTry","newTry","removeTry","pop","selectTryFromHeader","firstPendingTry","gradeFromHeader","nonGradableSyllabus","personalizedRemarks","showPersonalizedRemarks","personalizedRemarksChanged","usePersonalizedRemarks","addTraineeRemarksRow","selectedTraineeId","selectedTraineeName","newTraineeRemarks","deleteTraineeRemarks","traineeRemarks","isAddRemarksButtonDisabled","getAvailableTrainees","traineeValueChanged","hasSelectedTrainee","TraineeAimsId","allTrainees","selectedTraineeIds","remark","TraineeSignatureModalCtrl","signatureTrainee","confirmReset","traineeSign","credentials","Password","Username","authorizeTrainee","confirmation","trainingMenu","FullDate","StatusDesc","manageGroundCourseStatuses","Day","manageFlightCourseStatus","IsMultiday","getGroundCourseTrainees","groundDutyTraineeDutyNos","GroundDutyCodes","gdc","FilterByRole","flightCrewTrainee","_trainee$Session","getDutySessions","DebugCtrl","DebugFactory","adminkey","authorized","storedValues","addKeyName","checkAuthorized","verify","md5hash","CheckAuthorized","refreshStoredValues","Data","exit","updateAll","updateAllJson","ResetDeviceCtrl","cancelReset","Registrations","wifiVouchers","retrieve","pnrNo","isFlightView","vouchersFailedCallBack","requestObj","retrieveVouchersSuccessCallBack","Vouchers","createVouchersSuccessCallBack","getACSuppliesFromStorage","getACSuppliesFromStorageAsStrings","BarTrolleyCtrl","ModalDialogResultFactory","BarTrolley","SealFound","SealLeft","PhotoRemarks","CCMSCrewPositionCtrl","CCMSCrewPosition","FirstAidKitCtrl","FirstAidKit","FlightDetailCtrl","reportAircraftTypes","allAircraftTypes","IncompleteServicesIssueCtrl","a3Reasons","getA3ReasonsFromStorage","oaReasons","getOAReasonsFromStorage","a3Services","getA3ServicesFromStorage","oaServices","getOAServicesFromStorage","availableReasons","availableServices","clearIncompleteServiceRemarks","addRows","Rows","removeRow","IncompleteService","A3Reasons","OAReasons","A3Services","ItemPhotosCtrl","comment","settingsSet","settingsName","settingsText","settingsMinus","settingsPlus","settingsDefault","imageChanged","imageError","rotateImageLeft","origImg","oc","createElement","octx","mozImageSmoothingEnabled","webkitImageSmoothingEnabled","translate","rotate","drawImage","restore","rotateImageRight","viewPhoto","pho","deletePhoto","MedicalIncidentCtrl","clearMedicalRemarks","clearMedicalSignature","MedicalIncident","Medicine","Signature","DoctorName","DoctorPhone","EMFAKUsed","OpenReportDialogCtrl","allServerReports","canCreateNewLocalReport","IsSameUser","serverReports","createNewLocalReport","openLocalReport","openServerReport","Photo","RemarksShort","SeatChangeCtrl","passengersList","alreadyChanged","getPassengers","clearChangedSeatsRemarks","editMode","check","isSeatAvailable","isNothingToReport","constSourceLocalOwn","constSourceLocalOther","SpecialMealIssueCtrl","smts","getSpecialMealTypesFromStorageAsStrings","dateOptions","formatYear","startingDay","stopPropagation","smss","getSpecialMealSourcesFromStorageAsStrings","clearSpecialMealIssueRemarks","ReturnDate","offset","toISOString","SpecialMealIssue","getSpecialMealSourcesFromStorage","SpecialMealType","specialMealType","formObjects","getSpecialMealTypesFromStorage","specialMealTypeList","getSpecialMealTypesFromStorageAsObjects","SupplyCtrl","supplyTypes","clearSupplyRemarks","Supply","TravelValueSealCtrl","TravelValueSeal","UPGDCtrl","eligiblePassengersList","getEligiblePassengers","clearUPGDRemarks"],"mappings":"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","file":"../a3.cabin.app.js","sourcesContent":["\"use strict\";\n\n//***Modal Dialog for Application Updates - non angular **/\nvar modalUpdates;\nvar isDownloanding = false;\nvar isCheckForUpdate = false;\n(function () {\n if ('applicationCache' in window && !('serviceWorker' in navigator)) {\n modalUpdates = $('.modal-updating').modal({\n backdrop: 'static',\n keyboard: true,\n show: false\n });\n\n modalUpdates.show = function () {\n modalUpdates.removeClass('update-success');\n modalUpdates.find('.progress').show();\n modalUpdates.find('.message-success').hide();\n modalUpdates.find('.message-danger').hide();\n modalUpdates.find('.message-no-update').hide();\n modalUpdates.find('.btn-update-retry').hide();\n modalUpdates.find('.btn-update-close').hide();\n modalUpdates.find('.btn-update-ok').hide();\n $('.modal-dialog').modal('hide');\n modalUpdates.modal('show');\n };\n\n modalUpdates.hide = function () {\n modalUpdates.modal('hide');\n };\n\n modalUpdates.success = function () {\n modalUpdates.show();\n modalUpdates.find('.progress').hide();\n modalUpdates.find('.message-success').show();\n modalUpdates.find('.message-danger').hide();\n modalUpdates.find('.message-no-update').hide();\n modalUpdates.find('.btn-update-retry').hide();\n modalUpdates.find('.btn-update-close').hide();\n modalUpdates.find('.btn-update-ok').show();\n modalUpdates.addClass('update-success');\n setTimeout(function () {\n modalUpdates.modal('hide');\n }, 2000);\n };\n\n modalUpdates.noUpdate = function () {\n modalUpdates.show();\n modalUpdates.find('.progress').hide();\n modalUpdates.find('.message-success').hide();\n modalUpdates.find('.message-danger').hide();\n modalUpdates.find('.message-no-update').show();\n modalUpdates.find('.btn-update-retry').hide();\n modalUpdates.find('.btn-update-close').hide();\n modalUpdates.find('.btn-update-ok').show();\n isCheckForUpdate = false;\n };\n\n modalUpdates.failure = function (errorMessage) {\n modalUpdates.show();\n modalUpdates.find('.progress').hide();\n modalUpdates.find('.message-success').hide();\n modalUpdates.find('.message-danger').show();\n modalUpdates.find('.message-no-update').hide();\n modalUpdates.find('.btn-update-retry').show();\n modalUpdates.find('.btn-update-close').show();\n modalUpdates.find('.btn-update-ok').hide(); //setTimeout(function(){location.reload();}, 2000);\n\n if (errorMessage && errorMessage != '') {\n modalUpdates.find('.update-error').text(errorMessage);\n } else {\n modalUpdates.find('.update-error').text('');\n }\n };\n\n modalUpdates.on('hidden.bs.modal', function (e) {\n var b = modalUpdates.hasClass('update-success');\n if (b) location.reload(true);\n });\n }\n}).call(void 0); //** ApplicationCache Events & Actions **//\n\n(function () {\n ////////////////////////////////////////////////////index scripts (cache)////////////////////////////////////////////////////\n if ('applicationCache' in window && !('serviceWorker' in navigator)) {\n // Convenience array of status values\n var cacheHandler = function cacheHandler() {};\n\n cacheHandler.cacheStatusValues = [];\n cacheHandler.cacheStatusValues[0] = 'uncached';\n cacheHandler.cacheStatusValues[1] = 'idle';\n cacheHandler.cacheStatusValues[2] = 'checking';\n cacheHandler.cacheStatusValues[3] = 'downloading';\n cacheHandler.cacheStatusValues[4] = 'updateready';\n cacheHandler.cacheStatusValues[5] = 'obsolete';\n\n cacheHandler.onDownloading = function (e) {\n isDownloanding = true;\n modalUpdates.show();\n cacheHandler.logEvent(e);\n };\n\n cacheHandler.onCached = function (e) {\n modalUpdates.hide();\n cacheHandler.logEvent(e);\n };\n\n cacheHandler.onChecking = function (e) {\n //ShowWaitDialog();\n cacheHandler.logEvent(e);\n };\n\n cacheHandler.onProgress = function (e) {};\n\n cacheHandler.onObsolete = function (e) {};\n\n cacheHandler.onError = function (e) {\n //debugger;\n var message = \"Could not download application updates due to an unexpected error.\\n\" + \"make sure that cache.manifest is being served with MIME type: text/cache-manifest\"; //actual error message if any\n\n if (e.message) message = e.message;\n console.error(message); //hide update dialog if visible\n\n if (isDownloanding) {\n modalUpdates.failure(message);\n } else {\n modalUpdates.hide();\n }\n };\n\n cacheHandler.onNoUpdate = function (e) {\n if (isCheckForUpdate) {\n modalUpdates.noUpdate();\n } else {\n modalUpdates.hide();\n }\n\n isDownloanding = false;\n cacheHandler.logEvent(e);\n };\n\n cacheHandler.onUpdateReady = function (e) {\n try {\n cache.swapCache();\n } catch (e) {}\n\n cacheHandler.logEvent(e);\n isDownloanding = false;\n modalUpdates.success(); //location.reload(true);\n }; // Log every event to the console\n\n\n cacheHandler.logEvent = function (e) {// var status, type, message; //online,\n // //online = (navigator.online) ? 'yes' : 'no';\n // status = cacheHandler.cacheStatusValues[cache.status];\n // type = e.type;\n // message = '';//'online: ' + online;\n // message += 'CACHE: event: ' + type;\n // message += ', status: ' + status;\n // if (type == 'error' && navigator.online) {\n // message += ' (prolly a syntax error in manifest)';\n // }\n // console.log(message);\n };\n\n var cache = window.applicationCache;\n cache.addEventListener('cached', cacheHandler.onCached, false);\n cache.addEventListener('checking', cacheHandler.onChecking, false);\n cache.addEventListener('downloading', cacheHandler.onDownloading, false);\n cache.addEventListener('error', cacheHandler.onError, false); //cache.addEventListener('error', cacheHandler.logEvent, false);\n\n cache.addEventListener('noupdate', cacheHandler.onNoUpdate, false);\n cache.addEventListener('obsolete', cacheHandler.onObsolete, false);\n cache.addEventListener('progress', cacheHandler.onProgress, false);\n cache.addEventListener('updateready', cacheHandler.onUpdateReady, false);\n }\n\n $('#update-error-btn').click(function () {\n var alert = $('.hidden-update-error');\n\n if (alert.hasClass('hidden')) {\n alert.removeClass('hidden');\n $('#update-error-btn').text(\"show less\");\n } else {\n alert.addClass('hidden');\n $('#update-error-btn').text(\"show more\");\n }\n });\n $('body').on('click', '#update-check-btn', function () {\n isCheckForUpdate = true;\n var url = location.origin;\n $.ajax({\n type: \"GET\",\n url: url,\n cache: false,\n success: function success() {\n //get cache\n var cache = window.applicationCache; // Update the user's cache\n\n if (cache != null && cache != undefined && (cache.status == 1 || cache.status > 3)) {\n cache.update();\n }\n }\n /*,\r\n error: function(){\r\n console.log('error');\r\n }*/\n\n });\n });\n}).call(void 0);\n$(document).on(\"keydown\", '.modal textarea', function (e) {\n var zIndex = $(this).parents('.modal').css('z-index');\n\n if (zIndex) {\n $(this).parents('.modal').css('z-index', zIndex + 1);\n $(this).parents('.modal').css('z-index', zIndex);\n }\n});\n\"use strict\";\n\n$(function () {\n angular.bootstrap(document, ['a3.cabin.reports']);\n});\nvar a3_cabin_reports = angular.module('a3.cabin.reports', [//angular modules\n'ngSanitize', 'ngRoute', 'ngTouch', //3rd party modules\n'angular-md5', 'LocalStorageModule', 'ui.bootstrap', 'nya.bootstrap.select', 'ui.toggle', 'ui.sortable', //Our modules\n'MyDirectives', 'LocalStorageMD5Module']);\n\"use strict\";\n\n(function () {\n 'use strict'; // setup routing\n\n a3_cabin_reports.config(routeConfig);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name routeConfig\r\n * @description \r\n * Route configuration\r\n * @ngInject\r\n */\n\n function routeConfig($routeProvider) {\n $routeProvider.when('/', {\n controller: 'CalendarCtrl',\n templateUrl: 'views/calendar.html'\n }).when('/login', {\n controller: 'LoginCtrl',\n templateUrl: 'views/login.html'\n }).when('/flightinfo/:flightId', {\n controller: 'FlightInfoCtrl',\n templateUrl: 'views/flight-info.html',\n reloadOnSearch: false\n }).when('/selectedflightinfo/:flightId/:flightDate/:flightNo/:departure', {\n controller: 'SelectedFlightCtrl',\n templateUrl: 'views/SearchFlights/selected-flight-info.html',\n reloadOnSearch: false\n }).when('/leaverequest', {\n controller: 'LeaveRequestCtrl',\n templateUrl: 'views/LeaveRequest/leaveRequest.html'\n }).when('/pax/:flightId', {\n controller: 'PaxCtrl',\n templateUrl: 'views/pax.html'\n }).when('/report/:reportId/', {\n controller: 'ReportCtrl',\n templateUrl: 'views/report.html'\n }).when('/report/:reportId/:flightId', {\n controller: 'ReportCtrl',\n templateUrl: 'views/report.html'\n }).when('/pdf/:reportId', {\n controller: 'ReportCtrl',\n templateUrl: 'views/report.html'\n }).when('/reset', {\n controller: 'ResetDeviceCtrl',\n templateUrl: 'views/reset.html'\n }).when('/debug', {\n controller: 'DebugCtrl',\n templateUrl: 'views/debug.html'\n }).when('/assessment/:flightId', {\n controller: 'AssessmentCtrl',\n templateUrl: 'views/assessment.html'\n }).when('/faqs', {\n controller: 'FaqsCtrl',\n templateUrl: 'views/faqs.html'\n }).when('/rosterRequests', {\n controller: 'RequestsCtrl',\n templateUrl: 'views/RosterRequests/requests.html'\n }).when('/memos/:filter', {\n controller: 'MemosCtrl',\n templateUrl: 'views/memos.html'\n }).when('/memos', {\n controller: 'MemosCtrl',\n templateUrl: 'views/memos.html'\n }).when('/messages/:flightId', {\n controller: 'MessageCtrl',\n templateUrl: 'views/messages.html'\n }).when('/messages/', {\n controller: 'MessageCtrl',\n templateUrl: 'views/messages.html'\n }).when('/ticket', {\n controller: 'TicketCtrl',\n templateUrl: 'views/ticket.html'\n }).when('/bucket', {\n controller: 'BucketCtrl',\n templateUrl: 'views/Bucket/bucketCalendar.html'\n }).when('/bucketDay/:dutyId', {\n controller: 'BucketDayCtrl',\n templateUrl: 'views/Bucket/bucketDay.html'\n }).when('/groundDuty/:groundDutyId', {\n controller: 'GroundDutyCtrl',\n templateUrl: 'views/GroundDuty/groundDuty-info.html'\n }).when('/crewRoute/:dutyNo/:dutyDay', {\n controller: 'CrewRouteCtrl',\n templateUrl: 'views/CrewRoute/crew-route-info.html'\n }).when('/reportsHistory/:reportId/:flightId/:reportType', {\n controller: 'ReportsHistoryCtrl',\n templateUrl: 'views/reportsHistory.html'\n }).when('/flightcourse/:courseId/:dutyNo/:dutyDay/:date', {\n controller: 'FlightCourseCtrl',\n templateUrl: 'views/Training/flightCourse.html'\n }).when('/flightcourse/:courseId/:dutyNo/:dutyDay/:date/:flightId', {\n controller: 'FlightCourseCtrl',\n templateUrl: 'views/Training/flightCourse.html'\n }).when('/groundcourse/:courseId/:dutyId/:date', {\n controller: 'GroundCourseCtrl',\n templateUrl: 'views/Training/groundCourse.html'\n }).when('/safetyreport/cabincrewreport/:flightId', {\n controller: 'SafetyCtrl',\n templateUrl: 'views/Safety/cabinCrewReport.html'\n }).when('/safetyreport/fatiguereport/:flightId', {\n controller: 'FatigueCtrl',\n templateUrl: 'views/Safety/fatigueReport.html'\n }).when('/groundHistory/:courseId/:dutyId/:date/:phaseId', {\n controller: 'ModuleHistoryCtrl',\n templateUrl: 'views/Training/moduleHistory.html'\n }).when('/flightHistory/:courseId/:dutyNo/:dutyDay/:date/:phaseId', {\n controller: 'ModuleHistoryCtrl',\n templateUrl: 'views/Training/moduleHistory.html'\n }).when('/traineecourse/:traineeCourseId/:dutyId/:date', {\n controller: 'TraineeCourseCtrl',\n templateUrl: 'views/TraineeCourse/trainee-course.tpl.html'\n }).when('/mealLibrary', {\n controller: 'PassengerMealsCtrl',\n templateUrl: 'views/PassengerMealsInfo/mealsLibrary.html'\n }).otherwise({\n redirectTo: '/'\n });\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.run(runBlock);\n /* @ngInject */\n\n function runBlock($rootScope, $timeout, $location, $anchorScroll, UserFactory, UserTokenFactory, $templateCache, SettingsMain, SWUpdateService, CabinReportLocalEditFactory, CrewAssessmentFactory, PaxInfoFactory, LogService) {\n //make sure that each route change validates that the user is still logged in\n var valid = ['/login', '/reset', '/debug', '/ticket'];\n $rootScope.$on('$routeChangeStart', function (event, next, current) {\n if (valid.indexOf($location.$$path) < 0 && !UserFactory.isLoggedIn()) {\n event.preventDefault();\n $location.path('/login');\n } //START - SERVICE WORKERS\n\n\n if ('serviceWorker' in navigator) {\n SWUpdateService.initialize();\n navigator.serviceWorker.getRegistration().then(function (registration) {\n $rootScope.SWRegistration = registration;\n });\n SWUpdateService.checkUpdates($rootScope.SWRegistration);\n } //END - SERVICE WORKERS\n\n\n $anchorScroll.yOffset = 100;\n\n if (valid.indexOf($location.$$path) < 0 && (!current || !current.$$route || !next.$$route || current.$$route.controller != next.$$route.controller)) {\n //Check if temp report of any kind exists\n var editingPage = SettingsMain.getEditingPage();\n SettingsMain.setEditingPage(null);\n\n if (editingPage == 'report') {\n // check if a temp report exists in local storage\n if (CabinReportLocalEditFactory.getCabinReportLocalEditFromTemp() != null) {\n $location.path(\"report/temp\");\n }\n } else if (editingPage == 'assessment') {\n // check if a temp assessment exists in local storage\n if (CrewAssessmentFactory.getTempAssessment() != null) {\n $location.path(\"assessment/temp\");\n }\n } //Method: Clear specific cache on route change\n\n\n if (typeof current !== 'undefined') {\n $templateCache.remove(current.templateUrl);\n }\n }\n });\n $rootScope.idbSupported = \"indexedDB\" in window;\n $rootScope.isOffline = !window.navigator.onLine;\n window.addEventListener('offline', function (e) {\n $timeout($rootScope.isOffline = !window.navigator.onLine);\n });\n window.addEventListener('online', function (e) {\n $timeout($rootScope.isOffline = !window.navigator.onLine);\n });\n $(\"body\").on(\"click\", \".memo-body a\", function () {\n var link = $(this).attr(\"href\");\n\n if (link && link.indexOf(\"surveymonkey\") > 0) {\n LogService.debug(link);\n }\n }); //maintain the user token, outside the localStorage, needed for submitting js errors\n\n var user = UserFactory.getUser();\n if (user && user.token) UserTokenFactory.setToken(user.token);else UserTokenFactory.setToken('');\n }\n})();\n\"use strict\";\n\n(function () {\n // Warning!!! This an auto generated file. Any Changes will be lost. If u want to add or edit go to config.json \n a3_cabin_reports.constant(\"liveVersion\", true);\n a3_cabin_reports.constant(\"defaultCalendarDate\", null);\n a3_cabin_reports.constant(\"defaultBucketDate\", null);\n a3_cabin_reports.constant(\"apiUrl\", \"https://cabinreport.aegeanair.com/api/v1.34\");\n a3_cabin_reports.constant(\"azureADAuth\", {\n \"clientId\": \"064e4b4c-57b9-434f-aee8-28156709fab8\",\n \"tenantId\": \"00ab5264-f7ed-4d89-9011-19bf33ed8169\",\n \"authority\": \"https://login.microsoftonline.com/aegeancloud.onmicrosoft.com\"\n });\n a3_cabin_reports.constant(\"customerIncidentQuestionIds\", [220, 222]);\n a3_cabin_reports.constant(\"enableFaceMasks\", false);\n a3_cabin_reports.constant(\"ssrCodes\", [{\n \"code\": \"AOXY\",\n \"description\": \"Airline Supplied Oxygen\"\n }, {\n \"code\": \"AVIH\",\n \"description\": \"Animal in Hold\"\n }, {\n \"code\": \"AVML\",\n \"description\": \"Vegetarian Hindu meal\"\n }, {\n \"code\": \"BBNL\",\n \"description\": \"Baby meal request\"\n }, {\n \"code\": \"BIKE\",\n \"description\": \"Request for carriage of bicycle\"\n }, {\n \"code\": \"BLML\",\n \"description\": \"Bland meal request\"\n }, {\n \"code\": \"BLND\",\n \"description\": \"Blind passenger information\"\n }, {\n \"code\": \"CBBG\",\n \"description\": \"Bulky cabin baggage request\"\n }, {\n \"code\": \"CHLD\",\n \"description\": \"Child information\"\n }, {\n \"code\": \"CHML\",\n \"description\": \"Child Meal Request\"\n }, {\n \"code\": \"DBML\",\n \"description\": \"Diabetic meal request\"\n }, {\n \"code\": \"DEAF\",\n \"description\": \"Deaf passenger information\"\n }, {\n \"code\": \"DEPA\",\n \"description\": \"Accompanied Deportee Information\"\n }, {\n \"code\": \"DEPU\",\n \"description\": \"Deportee unaccompanied\"\n }, {\n \"code\": \"DHCS\",\n \"description\": \"Deadhead crew seating\"\n }, {\n \"code\": \"DPNA\",\n \"description\": \"Disabled passenger needing assistance\"\n }, {\n \"code\": \"EMIG\",\n \"description\": \"Emigrant\"\n }, {\n \"code\": \"ESAN\",\n \"description\": \"Passenger with emotional support/psychiatric\"\n }, {\n \"code\": \"ESCD\",\n \"description\": \"Passenger escorting deportee\"\n }, {\n \"code\": \"EXST\",\n \"description\": \"Request for extra seat\"\n }, {\n \"code\": \"FAMS\",\n \"description\": \"Family seating\"\n }, {\n \"code\": \"FPML\",\n \"description\": \"Fruit platter meal request\"\n }, {\n \"code\": \"FRED\",\n \"description\": \"Meal and assist request\"\n }, {\n \"code\": \"GFML\",\n \"description\": \"Gluten intolerant meal request\"\n }, {\n \"code\": \"GPST\",\n \"description\": \"Group seating request\"\n }, {\n \"code\": \"HAJJ\",\n \"description\": \"HAJJ Passengers\"\n }, {\n \"code\": \"HNML\",\n \"description\": \"Hindu meal request\"\n }, {\n \"code\": \"INAD\",\n \"description\": \"Inadmissable\"\n }, {\n \"code\": \"INFT\",\n \"description\": \"Infant information\"\n }, {\n \"code\": \"KSML\",\n \"description\": \"Kosher meal request\"\n }, {\n \"code\": \"LCML\",\n \"description\": \"Low calorie meal request\"\n }, {\n \"code\": \"LFML\",\n \"description\": \"Low fat meal request\"\n }, {\n \"code\": \"LSML\",\n \"description\": \"Low salt meal request\"\n }, {\n \"code\": \"MAAS\",\n \"description\": \"Meet and assist request\"\n }, {\n \"code\": \"MEDA\",\n \"description\": \"Medical assistance information\"\n }, {\n \"code\": \"MEQT\",\n \"description\": \"Medical equipment\"\n }, {\n \"code\": \"MOML\",\n \"description\": \"Halaal meal request\"\n }, {\n \"code\": \"NFML\",\n \"description\": \"No fish meal request\"\n }, {\n \"code\": \"NLML\",\n \"description\": \"Low lactose meal request\"\n }, {\n \"code\": \"NOML\",\n \"description\": \"Meal on board not required\"\n }, {\n \"code\": \"PETC\",\n \"description\": \"Pet in cabin request\"\n }, {\n \"code\": \"POXY\",\n \"description\": \"Passenger own oxygen\"\n }, {\n \"code\": \"RVML\",\n \"description\": \"Vegetarian raw meal request\"\n }, {\n \"code\": \"SEML\",\n \"description\": \"Seafood meal request\"\n }, {\n \"code\": \"SFML\",\n \"description\": \"Seafood meal request\"\n }, {\n \"code\": \"SPML\",\n \"description\": \"Special meal request\"\n }, {\n \"code\": \"SVAN\",\n \"description\": \"Passenger with service animal in cabin\"\n }, {\n \"code\": \"UMNR\",\n \"description\": \"Unaccompanied minor information\"\n }, {\n \"code\": \"VGML\",\n \"description\": \"Vegetarian vegan meal request\"\n }, {\n \"code\": \"VJML\",\n \"description\": \"Vegetarian Jain meal request\"\n }, {\n \"code\": \"VLML\",\n \"description\": \"Vegetarian Lacto-Ovo meal request\"\n }, {\n \"code\": \"VOML\",\n \"description\": \"Vegetarian Oriental meal request\"\n }, {\n \"code\": \"WCBD\",\n \"description\": \"Wheelchair Dry-cell battery request\"\n }, {\n \"code\": \"WCBW\",\n \"description\": \"Wheelchair Wet-cell battery request\"\n }, {\n \"code\": \"WCHC\",\n \"description\": \"Wheelchair To seat request\"\n }, {\n \"code\": \"WCHR\",\n \"description\": \"Wheelchair To aircraft door request\"\n }, {\n \"code\": \"WCHS\",\n \"description\": \"Wheelchair Up/down stairs request\"\n }, {\n \"code\": \"WCLB\",\n \"description\": \"Wheelchair - Lithium ion Battery\"\n }, {\n \"code\": \"WCMP\",\n \"description\": \"Wheelchair Manual powered request\"\n }, {\n \"code\": \"WCOB\",\n \"description\": \"Wheelchair On board request\"\n }, {\n \"code\": \"WEAP\",\n \"description\": \"WEAP Firearms or ammunition booked & carried as checked\"\n }, {\n \"code\": \"XBGS\",\n \"description\": \"DCS Excess Baggage Request\"\n }, {\n \"code\": \"FAML\",\n \"description\": \"BC HB choice A\"\n }, {\n \"code\": \"FBML\",\n \"description\": \"BC HB choice B\"\n }, {\n \"code\": \"BFML\",\n \"description\": \"BC HML beef choice\"\n }, {\n \"code\": \"CKML\",\n \"description\": \"BC HML chicken choice\"\n }, {\n \"code\": \"FSML\",\n \"description\": \"BC HML fish choice\"\n }, {\n \"code\": \"COML\",\n \"description\": \"Cold cut platter\"\n }, {\n \"code\": \"DEML\",\n \"description\": \"Dessert choice\"\n }]);\n a3_cabin_reports.constant(\"bookmarkThreshold\", 15);\n a3_cabin_reports.constant(\"turnArroundTimesAcTypes\", [\"319\", \"320\", \"321\", \"32Q\", \"32N\", \"32X\"]);\n a3_cabin_reports.constant(\"waterUpliftSupportingAcTypes\", [\"319\", \"320\", \"321\", \"32Q\", \"32N\", \"32X\"]);\n a3_cabin_reports.constant(\"enableWaterUpliftReporting\", false);\n a3_cabin_reports.constant(\"operationalPhases\", [{\n \"key\": \"3287\",\n \"value\": \"On Stand\"\n }, {\n \"key\": \"3288\",\n \"value\": \"Towing\"\n }, {\n \"key\": \"9242\",\n \"value\": \"Towing - Stand to Stand\"\n }, {\n \"key\": \"9243\",\n \"value\": \"Towing - to/from maint\"\n }, {\n \"key\": \"3289\",\n \"value\": \"Parked\"\n }, {\n \"key\": \"3290\",\n \"value\": \"Pushback\"\n }, {\n \"key\": \"3291\",\n \"value\": \"Taxi-out\"\n }, {\n \"key\": \"3292\",\n \"value\": \"Take-off\"\n }, {\n \"key\": \"3293\",\n \"value\": \"Initial Climb\"\n }, {\n \"key\": \"3294\",\n \"value\": \"Climb\"\n }, {\n \"key\": \"3295\",\n \"value\": \"Cruise\"\n }, {\n \"key\": \"3296\",\n \"value\": \"Descent\"\n }, {\n \"key\": \"3297\",\n \"value\": \"Holding\"\n }, {\n \"key\": \"3298\",\n \"value\": \"Approach\"\n }, {\n \"key\": \"3299\",\n \"value\": \"Landing\"\n }, {\n \"key\": \"3300\",\n \"value\": \"Taxi-in\"\n }, {\n \"key\": \"3301\",\n \"value\": \"Maintenance\"\n }, {\n \"key\": \"3302\",\n \"value\": \"All\"\n }, {\n \"key\": \"3303\",\n \"value\": \"In Aircraft\"\n }, {\n \"key\": \"3304\",\n \"value\": \"In Position at Aircraft\"\n }, {\n \"key\": \"3305\",\n \"value\": \"In Transit To / From Stand\"\n }, {\n \"key\": \"3306\",\n \"value\": \"Moving on Stand\"\n }, {\n \"key\": \"3307\",\n \"value\": \"Positioning to Aircraft\"\n }, {\n \"key\": \"3308\",\n \"value\": \"Removing from Aircraft\"\n }, {\n \"key\": \"3309\",\n \"value\": \"Other\"\n }, {\n \"key\": \"3310\",\n \"value\": \"Hover\"\n }, {\n \"key\": \"3311\",\n \"value\": \"In Flight\"\n }, {\n \"key\": \"3312\",\n \"value\": \"Multiple\"\n }, {\n \"key\": \"3313\",\n \"value\": \"Parked On / By Stand\"\n }, {\n \"key\": \"9241\",\n \"value\": \"Arrival\"\n }, {\n \"key\": \"9244\",\n \"value\": \"Arrival - Marshaling\"\n }, {\n \"key\": \"9245\",\n \"value\": \"Arrival - Guidance\"\n }, {\n \"key\": \"9246\",\n \"value\": \"Servicing\"\n }, {\n \"key\": \"9247\",\n \"value\": \"Servicing - De-icing\"\n }, {\n \"key\": \"9248\",\n \"value\": \"Servicing - Fueling\"\n }, {\n \"key\": \"9249\",\n \"value\": \"Servicing - Catering\"\n }, {\n \"key\": \"9250\",\n \"value\": \"Servicing - Lavatory\"\n }, {\n \"key\": \"9251\",\n \"value\": \"Servicing - Water\"\n }, {\n \"key\": \"9252\",\n \"value\": \"Servicing - Cleaning\"\n }, {\n \"key\": \"9253\",\n \"value\": \"Servicing - Line Maint\"\n }, {\n \"key\": \"9254\",\n \"value\": \"Servicing - Coning\"\n }, {\n \"key\": \"9255\",\n \"value\": \"Servicing - GPU\"\n }, {\n \"key\": \"9256\",\n \"value\": \"Servicing - PCA\"\n }, {\n \"key\": \"9257\",\n \"value\": \"Servicing - Bridging\"\n }, {\n \"key\": \"9258\",\n \"value\": \"Servicing - Chocking\"\n }, {\n \"key\": \"9259\",\n \"value\": \"Loading\"\n }, {\n \"key\": \"9260\",\n \"value\": \"Loading - Passenger\"\n }, {\n \"key\": \"9261\",\n \"value\": \"Loading - Baggage\"\n }, {\n \"key\": \"9262\",\n \"value\": \"Loading - Cargo\"\n }, {\n \"key\": \"9263\",\n \"value\": \"Unloading\"\n }, {\n \"key\": \"9264\",\n \"value\": \"Unloading - Passenger\"\n }, {\n \"key\": \"9265\",\n \"value\": \"Unloading - Baggage\"\n }, {\n \"key\": \"9266\",\n \"value\": \"Unloading - Cargo\"\n }]);\n})();\n\"use strict\";\n\n(function () {\n // Warning!!! This an auto generated file. Any Changes will be lost. If u want to add or edit go to config.json \n a3_cabin_reports.constant(\"version\", \"appVersion_20250205104221\");\n})();\n\"use strict\";\n\n(function () {\n 'use strict'; //Default Configuration For Charts\n\n a3_cabin_reports.constant('barOptions', barOptions);\n a3_cabin_reports.constant('pieDoughnutOptions', pieDoughnutOptions);\n var barOptions = {\n ///Boolean - Whether grid lines are shown across the chart\n scaleShowGridLines: true,\n //String - Colour of the grid lines\n scaleGridLineColor: \"rgba(0,0,0,.05)\",\n //Number - Width of the grid lines\n scaleGridLineWidth: 1,\n //Boolean - Whether to show horizontal lines (except X axis)\n scaleShowHorizontalLines: true,\n //Boolean - Whether to show vertical lines (except Y axis)\n scaleShowVerticalLines: true,\n //Boolean - Whether the line is curved between points\n bezierCurve: true,\n //Number - Tension of the bezier curve between points\n bezierCurveTension: 0.4,\n //Boolean - Whether to show a dot for each point\n pointDot: true,\n //Number - Radius of each point dot in pixels\n pointDotRadius: 4,\n //Number - Pixel width of point dot stroke\n pointDotStrokeWidth: 1,\n //Number - amount extra to add to the radius to cater for hit detection outside the drawn point\n pointHitDetectionRadius: 20,\n //Boolean - Whether to show a stroke for datasets\n datasetStroke: true,\n //Number - Pixel width of dataset stroke\n datasetStrokeWidth: 2,\n //Boolean - Whether to fill the dataset with a colour\n datasetFill: true,\n //String - A legend template\n legendTemplate: \"\"\n };\n var pieDoughnutOptions = {\n //Boolean - Whether we should show a stroke on each segment\n segmentShowStroke: true,\n //String - The colour of each segment stroke\n segmentStrokeColor: \"#fff\",\n //Number - The width of each segment stroke\n segmentStrokeWidth: 2,\n //Number - The percentage of the chart that we cut out of the middle\n percentageInnerCutout: 50,\n // This is 0 for Pie charts\n //Number - Amount of animation steps\n animationSteps: 100,\n //String - Animation easing effect\n animationEasing: \"easeOutBounce\",\n //Boolean - Whether we animate the rotation of the Doughnut\n animateRotate: true,\n //Boolean - Whether we animate scaling the Doughnut from the centre\n animateScale: false,\n //String - A legend template\n legendTemplate: \"\",\n onAnimationComplete: function onAnimationComplete() {\n this.showTooltip(this.segments, true);\n },\n tooltipEvents: [],\n showTooltips: true\n };\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n angular.module('MyDirectives', [])\n /**\r\n * HTML5 SignaturePad Directive\r\n * This directive is intended to place a canvas within a form\r\n * which can then be drawn upon. Once it is drawn updon, it will be\r\n * considered 'valid'\r\n *\r\n * Thanks to Thomas J Bradley for the Signature Pad plugin for jQuery\r\n * http://thomasjbradley.ca/lab/signature-pad/\r\n *\r\n */\n .directive('sigpad', function ($timeout) {\n return {\n templateUrl: 'views/sigPad.html',\n // Use a template in an external file\n restrict: 'E',\n // Must use element to invoke directive\n scope: true,\n // Create a new scope for the directive\n require: 'ngModel',\n // Require the ngModel controller for the linking function\n link: function link(scope, element, attr, ctrl) {\n // Attach the Signature Pad plugin to the template and keep a reference to the signature pad as 'sigPadAPI'\n var sigPadAPI = $(element).signaturePad({\n drawOnly: true,\n lineColour: '#FFF',\n penWidth: 6\n }); // Clear the canvas when the 'clear' button is clicked\n\n $(attr.clearbtn).on('click', function (e) {\n sigPadAPI.clearCanvas();\n });\n $(element).find('.pad').on('touchend', function (obj) {\n scope.updateModel();\n }); // when the mouse is lifted from the canvas, set the signature pad data as the model value\n\n scope.updateModel = function () {\n $timeout(function () {\n var sig = sigPadAPI.getSignature();\n\n if (sig != null && sig.length == 0) {\n var sig = null;\n }\n\n ctrl.$setViewValue(sig);\n });\n }; // Render the signature data when the model has data. Otherwise clear the canvas.\n\n\n ctrl.$render = function () {\n if (ctrl.$viewValue) {\n sigPadAPI.regenerate(ctrl.$viewValue);\n } else {\n // This occurs when signatureData is set to null in the main controller\n sigPadAPI.clearCanvas();\n }\n }; // Validate signature pad.\n // See http://docs.angularjs.org/guide/forms for more detail on how this works.\n\n\n ctrl.$parsers.unshift(function (viewValue) {\n if (sigPadAPI.validateForm()) {\n ctrl.$setValidity('sigpad', true);\n return viewValue;\n } else {\n ctrl.$setValidity('sigpad', false); //undefined to viewValue cause of bug\n\n return viewValue;\n }\n });\n }\n };\n })\n /**\r\n * Regenerate Signature Pad data as Base64 encoded PNG data.\r\n * This uses the getSignatureImage() function of the Signature Pad API.\r\n * It only works in modern browsers, and is flaky in IE.\r\n */\n .directive('regensigpad', function () {\n return {\n template: '',\n restrict: 'E',\n scope: {\n sigdata: '@'\n },\n link: function link(scope, element, attr, ctrl) {\n // When the sigdata attribute changes...\n attr.$observe('sigdata', function (val) {\n // ... create a blank canvas template and attach the signature pad plugin\n var sigPadAPI = $('
').signaturePad({\n displayOnly: true\n }); // regenerate the signature onto the canvas\n\n if (val) {\n sigPadAPI.regenerate(val);\n } else {\n // This occurs when signatureData is set to null in the main controller\n sigPadAPI.clearCanvas();\n } // convert the canvas to a PNG (Newer versions of Chrome, FF, and Safari only.)\n\n\n scope.pic = sigPadAPI.getSignatureImage();\n });\n }\n };\n })\n /* Used to capture images from the device's camera\r\n * and resize them using given dimensions and quality\r\n * \r\n */\n .directive('image', function ($q) {\n 'use strict';\n\n var URL = window.URL || window.webkitURL;\n return {\n restrict: 'A',\n scope: {\n /*image: '=',*/\n maxwidth: '@?',\n maxheight: '@?',\n quality: '@?',\n imagetype: '@?',\n onfilechange: '&'\n },\n link: function postLink(scope, element, attrs, ctrl) {\n var onFileChangeCallback = scope.onfilechange;\n var onFileFailureCallback = scope.onfileerror;\n var filename = \"\";\n var options;\n\n var getOptions = function getOptions() {\n var options = {\n maxWidth: parseFloat(scope.maxwidth) || 1024,\n maxHeight: parseFloat(scope.maxheight) || 768,\n quality: parseFloat(scope.quality) || 0.8,\n imageType: scope.imagetype || 'image/jpeg',\n canvas: true\n };\n return options;\n };\n\n var whenError = function whenError(errorMessage) {\n scope.$apply(function () {\n if (typeof onFileFailureCallback == 'function') {\n //to pass data in the message, we need to have an object with attrs named as in\n //the html part, eg onfilechange=\"imageChanged(data)\"\n onFileFailureCallback({\n err: errorMessage\n });\n }\n });\n };\n\n var whenReady = function whenReady(img) {\n if (!(img.src || img instanceof HTMLCanvasElement)) {\n whenError('Loading image file failed');\n } else {\n var data = img.src || img.toDataURL(options.imageType, options.quality);\n var imageResult = {\n dataURL: data,\n fileName: filename,\n fileType: options.imageType\n };\n scope.$apply(function () {\n if (typeof onFileChangeCallback == 'function') {\n //to pass data in the message, we need to have an object with attrs named as in\n //the html part, eg onfilechange=\"imageChanged(data)\"\n onFileChangeCallback({\n data: imageResult\n });\n }\n });\n }\n };\n\n element.bind('change', function (evt) {\n evt.preventDefault(); //e = e.originalEvent;\n\n var target = evt.dataTransfer || evt.target;\n var files = target && target.files;\n\n if (files) {\n var file;\n options = getOptions(); //read latest settings\n\n for (var i = 0; i < files.length; i++) {\n file = files[i];\n filename = file.name; //start by get metadata, to autoset the orientation of the image\n\n loadImage.parseMetaData(file, //when metadata are ready, use them and then load image\n function (data) {\n if (data.exif) {\n options.orientation = data.exif.get('Orientation');\n }\n\n if (!loadImage(file, whenReady, options)) {\n whenError('Your browser does not support capturing images.');\n }\n });\n }\n }\n });\n }\n };\n }).directive('integer', function () {\n return {\n require: 'ngModel',\n link: function link(scope, elm, attrs, ctrl) {\n ctrl.$parsers.unshift(function (viewValue) {\n var INTEGER_REGEXP = /^\\-?\\d+$/;\n\n if (INTEGER_REGEXP.test(viewValue)) {\n // it is valid\n ctrl.$setValidity('integer', true);\n return viewValue;\n } else {\n // it is invalid, return undefined (no model update)\n ctrl.$setValidity('integer', false);\n return undefined;\n }\n });\n }\n };\n }).directive('smartFloat', function () {\n return {\n require: 'ngModel',\n link: function link(scope, elm, attrs, ctrl) {\n ctrl.$parsers.unshift(function (viewValue) {\n var FLOAT_REGEXP = /^\\-?\\d+((\\.|\\,)\\d+)?$/;\n\n if (FLOAT_REGEXP.test(viewValue)) {\n ctrl.$setValidity('float', true);\n return parseFloat(viewValue.replace(',', '.'));\n } else {\n ctrl.$setValidity('float', false);\n return undefined;\n }\n });\n }\n };\n }).directive('validNumber', function () {\n return function (scope, element, attrs) {\n // var keyCode = [8,9,37,39, 46,48,49,50,51,52,53,54,55,56,57 ,96,97,98,99,100,101,102,103,104,105,110];\n var keyCode = [8, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 110, 190];\n element.bind(\"keydown\", function (event) {\n if ($.inArray(event.which, keyCode) == -1) {\n scope.$apply(function () {\n scope.$eval(attrs.onlyNum);\n event.preventDefault();\n });\n event.preventDefault();\n }\n });\n };\n }).directive('chart', function () {\n var baseWidth = 600;\n var baseHeight = 400;\n return {\n restrict: 'E',\n template: '',\n scope: {\n chartObject: \"=value\"\n },\n link: function link(scope, element, attrs) {\n var canvas = element.find('canvas')[0];\n var context = canvas.getContext('2d');\n var chart;\n var options = {\n type: attrs.type || \"Line\",\n width: attrs.width || baseWidth,\n height: attrs.height || baseHeight\n };\n canvas.width = options.width;\n canvas.height = options.height;\n chart = new Chart(context);\n\n if (scope.chartObject) {\n scope.$watch(function () {\n return element.attr('type');\n }, function (value) {\n if (!value) return;\n options.type = value;\n var chartType = options.type;\n chart[chartType](scope.chartObject.data, scope.chartObject.options);\n }); //Update when charts data changes\n\n scope.$watch(function () {\n return scope.chartObject;\n }, function (value) {\n if (!value) return;\n var chartType = options.type;\n chart[chartType](scope.chartObject.data, scope.chartObject.options);\n if (scope.chartInstance) scope.chartInstance.destroy();\n scope.chartInstance = chart[chartType](scope.chartObject.data, scope.chartObject.options);\n }, true);\n }\n }\n };\n }).directive('canvasGauge', function () {\n return {\n restrict: 'E',\n replace: true,\n template: '',\n scope: {\n val: '=value'\n },\n link: function link($scope, element, attrs) {\n var width = parseInt(attrs.width || '100');\n $scope.height = width * 0.55;\n element.attr('height', $scope.height + 'px');\n var placeholder = attrs.placeholder || '(@)';\n var mask = attrs.mask || placeholder;\n var canvas = element[0];\n var animID = 0;\n var curValue = 0;\n var endValue = 0;\n var oldValue = 0;\n var direction = 0;\n\n var render = function render(val) {\n var value = val || 0;\n\n if (canvas.getContext) {\n var ctx = canvas.getContext('2d');\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n\n var calcPercent = function calcPercent(total, perc) {\n return total * perc / 100;\n };\n\n var per = (value - $scope.min) * 100 / ($scope.max - $scope.min); // Value converted to percentage using min and max\n\n var pad = calcPercent(canvas.width, 15); // Inner padding around the container\n\n var x = canvas.width / 2; // x coordinate\n\n var y = canvas.width / 2.3; // y coordinate\n\n var startAngle = 0; // Starting point on circle\n\n var radius = x - pad; // Circle's radius\n\n var lineWidth = canvas.width / 8; // Thickness of the drawing tip\n\n var fontSize = canvas.width * 0.1; // Default size of the text font (10% of canvas width)\n\n ctx.imageSmoothingEnabled = true;\n ctx.shadowOffsetX = 0;\n ctx.shadowOffsetY = 0;\n ctx.shadowBlur = 0;\n ctx.beginPath();\n ctx.arc(x, y, radius, Math.PI, Math.PI * 2, false);\n ctx.lineWidth = lineWidth;\n ctx.strokeStyle = $scope.underColor;\n ctx.stroke();\n ctx.closePath();\n var endAngle = Math.PI * per / 100 + Math.PI;\n ctx.beginPath();\n ctx.arc(x, y, radius, Math.PI, endAngle, false);\n ctx.lineWidth = lineWidth;\n ctx.strokeStyle = $scope.overColor;\n ctx.stroke();\n ctx.closePath();\n ctx.font = 'bold ' + fontSize + 'pt Calibri';\n ctx.textAlign = 'center';\n ctx.fillStyle = $scope.textColor;\n ctx.shadowColor = $scope.shadeColors($scope.smallTextColor, -30);\n ctx.shadowOffsetX = 1;\n ctx.shadowOffsetY = 1;\n ctx.shadowBlur = 0;\n ctx.fillText(mask.replace(placeholder, parseFloat(value.toFixed(2)).toString()), x, y);\n\n if (canvas.width > 119) {\n y = canvas.width / 2.2 + calcPercent(canvas.height, 10) + canvas.width / 100 - 1;\n x = pad;\n ctx.font = 'normal ' + fontSize / 2 + 'pt Calibri';\n ctx.shadowOffsetX = 0;\n ctx.shadowOffsetY = 0;\n ctx.fillStyle = $scope.smallTextColor;\n ctx.fillText($scope.min, x, y);\n y = canvas.width / 2.2 + calcPercent(canvas.height, 10) + canvas.width / 100 - 1;\n x = canvas.width - pad;\n ctx.font = 'normal ' + fontSize / 2 + 'pt Calibri';\n ctx.fillStyle = $scope.smallTextColor;\n ctx.fillText($scope.max, x, y);\n }\n }\n };\n\n var animate = function animate() {\n var flag = direction == 1 ? curValue <= endValue : curValue >= endValue;\n\n if (flag == true) {\n render(curValue);\n curValue += direction;\n animID = requestAnimationFrame(animate);\n } else {\n oldValue = endValue;\n render(endValue);\n cancelAnimationFrame(animID);\n }\n };\n\n $scope.shadeColors = function (color, percent) {\n var f = parseInt(color.slice(1), 16),\n t = percent < 0 ? 0 : 255;\n var p = percent < 0 ? percent * -1 : percent;\n var R = f >> 16;\n var G = f >> 8 & 0x00FF;\n var B = f & 0x0000FF;\n return \"#\" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);\n };\n\n $scope.$watch('val', function (newval, oldval) {\n $scope.min = attrs.min || 0;\n $scope.max = attrs.max || 100;\n $scope.underColor = attrs.underColor || '#EFEFEF';\n $scope.overColor = attrs.overColor || '#000';\n $scope.textColor = attrs.textColor || $scope.overColor;\n $scope.smallTextColor = attrs.smallTextColor || getComputedStyle(element[0]).getPropertyValue(\"color\");\n curValue = parseFloat(oldValue);\n endValue = parseFloat(newval); //alert(curValue + ' -- ' + endValue);\n\n direction = endValue < curValue ? -1 : 1;\n animate();\n });\n }\n };\n }).directive('bsHasError', [function () {\n return {\n restrict: \"A\",\n link: function link(scope, element, attrs, ctrl) {\n var input = element.find('input[ng-model]');\n\n if (input) {\n scope.$watch(function () {\n return input.hasClass('ng-invalid') && input.hasClass('ng-dirty');\n }, function (isInvalid) {\n element.toggleClass('has-error', isInvalid);\n });\n }\n }\n };\n }]);\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('AirportContactFactory', AirportContactFactory);\n /**\r\n * @memberof PilotReports\r\n * @ngdoc factory\r\n * @name AirportContactFactory\r\n * @description \r\n * Add, Update, Delete and Get Airport Contacts.\r\n * @ngInject\r\n */\n\n function AirportContactFactory(GenericService) {\n /**\r\n * Initialize the AirportContact\r\n * @memberof AirportContactFactory\r\n */\n function Airport() {\n this.Iata = null;\n this.Contacts = null;\n }\n\n var objType = 'airportContacts';\n var objCallback = Airport;\n var service = {\n fromObjectList: fromObjectList,\n getAirportContactsFromStorage: getAirportContactsFromStorage,\n setAirportContactsToStorage: setAirportContactsToStorage,\n clearAirportContactsFromStorage: clearAirportContactsFromStorage,\n getAirportContacts: getAirportContacts,\n upsertAirportContacts: upsertAirportContacts\n };\n /**\r\n * Extend an array of Objects from the default airportContact Object\r\n * @memberof AirportContactFactory\r\n * @param {Array} objList an Array Of airportContact\r\n * @returns {Array} airportContact\r\n */\n\n function fromObjectList(objList) {\n return GenericService.fromObjectList(objList, objCallback);\n }\n /**\r\n * Get airportContacts\r\n * @memberof AirportContactFactory\r\n * @returns {Array} airportContacts\r\n */\n\n\n function getAirportContactsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save airportContacts to storage\r\n * @memberof AirportContactFactory\r\n * @param {Array} airportContacts A list of AirportContacts\r\n */\n\n\n function setAirportContactsToStorage(airportContacts) {\n GenericService.saveAll(airportContacts, objType, objCallback);\n }\n /**\r\n * Remove the airportContacts of the local storage\r\n * @memberof AirportContactFactory\r\n */\n\n\n function clearAirportContactsFromStorage() {\n GenericService.removeAll(objType, objCallback);\n }\n /**\r\n * Get the contacts for a given airport\r\n * @memberof AirportContactFactory\r\n */\n\n\n function getAirportContacts(airportIata) {\n var all = this.getAirportContactsFromStorage();\n if (!all) return null;\n var airport = all.filter(function (item) {\n return item.Iata == airportIata;\n });\n if (!airport || airport.length == 0) return null; //we expect a single airport item per iata\n\n return airport[0]; //return GenericService.fromObjectList(airport[0].Contacts, Contact);\n }\n /**\r\n * Upsert airport contacts\r\n * @memberof AirportContactFactory\r\n */\n\n\n function upsertAirportContacts(airportContacts) {\n var newStations = airportContacts.map(function (x) {\n return x.Iata;\n });\n var contactsLS = this.getAirportContactsFromStorage();\n contactsLS = contactsLS.filter(function (x) {\n return !newStations.includes(x.Iata);\n });\n var updatedContactList = contactsLS.concat(airportContacts);\n setAirportContactsToStorage(updatedContactList);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('AirportHotelFactory', AirportHotelFactory);\n /**\r\n * @memberof PilotReports\r\n * @ngdoc factory\r\n * @name AirportHotelFactory\r\n * @description \r\n * Add, Update, Delete and Get Airport Hotels.\r\n * @ngInject\r\n */\n\n function AirportHotelFactory(GenericService) {\n /**\r\n * Initialize the AirportHotel\r\n * @memberof AirportHotelFactory\r\n */\n function Airport() {\n this.Iata = null;\n this.Hotels = null;\n }\n\n var objType = 'airportHotels';\n var objCallback = Airport;\n var service = {\n fromObjectList: fromObjectList,\n getAirportHotelsFromStorage: getAirportHotelsFromStorage,\n setAirportHotelsToStorage: setAirportHotelsToStorage,\n clearAirportHotelsFromStorage: clearAirportHotelsFromStorage,\n getAirportHotels: getAirportHotels,\n upsertAirportHotels: upsertAirportHotels\n };\n /**\r\n * Extend an array of Objects from the default airportHotel Object\r\n * @memberof AirportHotelFactory\r\n * @param {Array} objList an Array Of airportHotel\r\n * @returns {Array} airportHotel\r\n */\n\n function fromObjectList(objList) {\n return GenericService.fromObjectList(objList, objCallback);\n }\n /**\r\n * Get airportHotels\r\n * @memberof AirportHotelFactory\r\n * @returns {Array} airportHotels\r\n */\n\n\n function getAirportHotelsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save airportHotels to storage\r\n * @memberof AirportHotelFactory\r\n * @param {Array} airportHotels A list of AirportHotels\r\n */\n\n\n function setAirportHotelsToStorage(airportHotels) {\n GenericService.saveAll(airportHotels, objType, objCallback);\n }\n /**\r\n * Remove the airportHotels of the local storage\r\n * @memberof AirportHotelFactory\r\n */\n\n\n function clearAirportHotelsFromStorage() {\n GenericService.removeAll(objType, objCallback);\n }\n /**\r\n * Get the Hotels for a given airport\r\n * @memberof AirportHotelFactory\r\n */\n\n\n function getAirportHotels(airportIata, fltDate) {\n var all = this.getAirportHotelsFromStorage();\n if (!all) return null;\n var airport = all.filter(function (item) {\n return item.Iata == airportIata;\n });\n if (!airport || airport.length == 0) return null; //for each airport hotel\n //from all available hotel priorities, find the one matching the active period \n\n angular.forEach(airport[0].Hotels, function (hotel) {\n var fltActiveHotels = hotel.HotelPriorities.filter(function (item) {\n return fltDate >= item.ActiveBegin && fltDate <= item.ActiveEnd;\n });\n if (!fltActiveHotels || fltActiveHotels.length == 0) return; //hotel inactive in FltDate - ActivePriority will be undefined for this hotel\n\n hotel.ActivePriority = fltActiveHotels[0].PriorityNo; //set the ActivePriority field for the hotel to be displayed in UI\n }); //we expect a single airport item per iata\n\n return airport[0]; //return GenericService.fromObjectList(airport[0].Hotels, Hotel);\n }\n /**\r\n * Upsert aircraft hotels\r\n * @memberof AirportHotelFactory\r\n */\n\n\n function upsertAirportHotels(airportHotels) {\n var newHotels = airportHotels.map(function (x) {\n return x.Iata;\n });\n var hotelsLS = this.getAirportHotelsFromStorage();\n hotelsLS = hotelsLS.filter(function (x) {\n return !newHotels.includes(x.Iata);\n });\n var updatedHotelsList = hotelsLS.concat(airportHotels);\n setAirportHotelsToStorage(updatedHotelsList);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('BucketCtrl', BucketCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name BucketCtrl\r\n * @description \r\n * View bucket\r\n * @ngInject\r\n */\n\n function BucketCtrl($scope, $location, BucketFactory, UserFactory, MessageFactory, $timeout, SettingsMain, defaultBucketDate) {\n var ownDuties = [];\n var sharedDuties = [];\n var approvedDuties = [];\n $scope.state = 'bucketCalendar';\n var user = UserFactory.getUser();\n $scope.isSecure = UserFactory.isSecure();\n $scope.isUserSA = user.position == 'SA' ? true : false;\n $scope.logged_user_info = user.aimsId + ' - ' + user.name;\n $scope.getCalendarData = getCalendarData;\n $scope.showErrorMessage = false;\n var selectedDate = SettingsMain.getCalendarSelectedDate(); //Redirect to month that was previously selected\n\n SettingsMain.setCalendarSelectedDate(null); //Then reinitialize to current month\n\n getCalendarData();\n\n function getCalendarData() {\n progressBarBox(true);\n BucketFactory.getDutyObject(function (responseData) {\n ownDuties = responseData.data.data.Duties;\n sharedDuties = responseData.data.data.SharedDuties;\n approvedDuties = responseData.data.data.ApprovedDuties;\n setupView();\n progressBarBox(false);\n })[\"catch\"](function (error) {\n $scope.showErrorMessage = true;\n progressBarBox(false);\n console.error('Load duties error', error.status, error.statusText);\n });\n }\n\n function setupView() {\n if (!UserFactory.isLoggedIn()) {\n $location.path(\"/login\");\n }\n\n $scope.number_of_messages = MessageFactory.getMessagesFromStorage().length;\n $scope.number_of_messages_not_readen = MessageFactory.getCountOfUnreadMessages();\n /*var ownEvents = formatDuties(ownDuties, true, false);\r\n if (sharedDuties.length > 0) {\r\n var sharedEvents = formatDuties(sharedDuties, false, false);\r\n var events = ownEvents.concat(sharedEvents);\r\n } else {\r\n var events = ownEvents;\r\n }*/\n\n $scope.notification = createNotification(ownDuties);\n var ownEvents = formatDuties(ownDuties, true, false);\n var events = ownEvents;\n\n if (approvedDuties != null || approvedDuties != undefined) {\n if (approvedDuties.length > 0) {\n var appvovedEvents = formatDuties(approvedDuties, true, true);\n var events = events.concat(appvovedEvents);\n }\n }\n\n calendar(events);\n }\n /**\r\n * Transform routes in calendar events\r\n * @memberof BucketCtrl\r\n * @param {array} routes - The Scheduled Routes \r\n * @return {array} events \r\n */\n\n\n function formatDuties(duties, isOwnDuty, isApproved) {\n var dutiesEvents = [];\n\n for (var i = 0; i < duties.length; i++) {\n if (duties[i].IsUpdated) {\n console.log(duties[i]);\n }\n /*************** Add main event for duty *********************/\n // var eType = (isOwnDuty ? 'own-' : 'shared-') + duties[i].DutyType.toLowerCase();\n\n\n var eClassName = getEventClassName(duties[i], isOwnDuty, isApproved);\n var eIcons = getEventIcons(duties[i], isOwnDuty, isApproved);\n var eTitle = getEventTitle(duties[i], isOwnDuty) + (duties[i].TotalSharedDuties == undefined ? \"\" : duties[i].TotalSharedDuties);\n var eOtherInfos = getOtherInfos(duties[i], isOwnDuty);\n var event = {\n _id: duties[i].Id,\n // type: eType,\n icons: eIcons,\n className: eClassName[\"class\"],\n title: eTitle,\n start: duties[i].DutyBegin == duties[i].DutyEnd ? duties[i].DutyDateS : duties[i].DutyBegin,\n end: duties[i].DutyBegin == duties[i].DutyEnd ? null : duties[i].DutyEnd,\n sortOrder: isOwnDuty ? 1 : -1,\n otherInfos: eOtherInfos,\n shareable: duties[i].Shareable,\n isOwnDuty: isOwnDuty,\n isApproved: isApproved,\n isOwnApproved: duties[i].HasApprovedProposals,\n listViewColor: eClassName.color\n };\n dutiesEvents.push(event);\n }\n\n return dutiesEvents;\n }\n\n function createNotification(duties) {\n var NewPendingProposalsCount = 0;\n var NewApprovedProposalsCount = 0;\n var NewRejectedProposalsCount = 0;\n var notificationText = null;\n\n for (var i = 0; i < duties.length; i++) {\n if (duties[i].IsUpdated) {\n if (duties[i].HasApprovedProposals) {\n NewApprovedProposalsCount++;\n } else {\n NewPendingProposalsCount += duties[i].NewPendingProposalsCount;\n NewRejectedProposalsCount += duties[i].NewRejectedProposalsCount;\n }\n }\n }\n /* var notification = {\r\n NewPendingProposalsCount : NewPendingProposalsCount,\r\n NewApprovedProposalsCount : NewApprovedProposalsCount,\r\n NewRejectedProposalsCount : NewRejectedProposalsCount\r\n }*/\n\n\n if (NewPendingProposalsCount + NewApprovedProposalsCount + NewRejectedProposalsCount > 0) {\n notificationText = \"You have \";\n var hasPrevious = false;\n\n if (NewPendingProposalsCount) {\n notificationText = notificationText + NewPendingProposalsCount + \" pending\";\n hasPrevious = true;\n }\n\n if (NewRejectedProposalsCount) {\n var conjuction = hasPrevious ? NewApprovedProposalsCount ? \", \" : \" and \" : \"\";\n notificationText = notificationText + conjuction + NewRejectedProposalsCount + \" rejected\";\n hasPrevious = true;\n }\n\n if (NewApprovedProposalsCount) {\n var conjuction = hasPrevious ? \" and \" : \"\";\n notificationText = notificationText + conjuction + NewApprovedProposalsCount + \" accepted\";\n }\n\n notificationText = notificationText + \" proposals.\";\n }\n\n return notificationText;\n }\n /**\r\n * Returns an array of strings for icons to display in the event tile\r\n * @memberof BucketCtrl\r\n * @param {object} duty - The Scheduled duty \r\n * @param {boolean} ownDuty - Is set to true when the duty is current user's duty, otherwise is set to false\r\n * @return {array} icons - The array of strings for icons to display in the event tile.\r\n */\n\n\n function getEventIcons(duty, isOwnDuty, isApproved) {\n var icons = [];\n if (!isOwnDuty) icons.push('fa-sing-in');else {\n if (duty.IsUpdated) icons.push('fa-star text-orange');\n /* if (duty.PendingProposalsCount > 0 && !isApproved) icons.push('fa-info-circle');*/\n\n if (!duty.Shareable || isApproved) icons.push('fa-lock');\n if (duty.Shared && !isApproved) icons.push('fa-bitbucket');\n }\n return icons;\n }\n /**\r\n * Returns the title for the event tile\r\n * @memberof BucketCtrl\r\n * @param {object} duty - The Scheduled duty \r\n * @param {boolean} ownDuty - Is set to true when the duty is current user's duty, otherwise is set to false\r\n * @return {string} title - The title to display in the event tile.\r\n */\n\n\n function getEventTitle(duty, isOwnDuty) {\n var title = '';\n if (isOwnDuty) title += duty.Title;else title += 'Shared duties: ';\n return title;\n }\n /**\r\n * Returns the class for the event tile\r\n * @memberof BucketCtrl\r\n * @param {object} duty - The Scheduled duty \r\n * @param {boolean} ownDuty - Is set to true when the duty is current user's duty, otherwise is set to false\r\n * @return {string} className - The class(es) to use for displaying the event tile.\r\n */\n\n\n function getEventClassName(duty, isOwnDuty, isApproved) {\n var eventClass = {\n \"class\": 'fc-bucket ',\n color: ''\n };\n\n if (isOwnDuty) {\n eventClass[\"class\"] += 'fc-own ';\n var hasApprovedTrade = duty.HasApprovedProposals;\n\n if (isApproved == true) {\n eventClass[\"class\"] += 'fc-green-inverted ';\n eventClass.color = 'lv-green-inverted';\n } else if (hasApprovedTrade) {\n eventClass[\"class\"] += 'fc-green ';\n eventClass.color = 'lv-green';\n } else if (duty.Shared) {\n eventClass[\"class\"] += 'fc-primary-inverted ';\n eventClass.color = 'lv-blue';\n }\n /* else if (duty.Shareable && duty.PendingProposalsCount == 0) {\r\n eventClass.class += 'fc-blue ';\r\n eventClass.color = 'lv-blue';\r\n } else if (duty.PendingProposalsCount > 0) {\r\n eventClass.class += 'fc-orange ';\r\n eventClass.color = 'lv-orange';\r\n } else if (duty.Bookmarks != undefined && duty.Bookmarks.length > 0) {\r\n eventClass.class += 'fc-purple-inverted ';\r\n eventClass.color = 'lv-purple-inverted';\r\n } */\n else {\n eventClass[\"class\"] += 'fc-white ';\n eventClass.color = 'lv-white';\n }\n } else {\n eventClass[\"class\"] += 'fc-aluminum ';\n eventClass.color = 'lv-aluminum';\n }\n\n return eventClass;\n }\n /**\r\n * Returns an array of objects for infos (label, number) to display in the event tile\r\n * @memberof BucketCtrl\r\n * @param {object} duty - The Scheduled duty \r\n * @param {boolean} ownDuty - Is set to true when the duty is current user's duty, otherwise is set to false\r\n * @return {array} infos - The array of objects for infos (label, number) to display in the event tile.\r\n */\n\n\n function getOtherInfos(duty, isOwnDuty) {\n var infos = [];\n\n if (isOwnDuty) {\n var hasApprovedTrade = duty.HasApprovedProposals;\n\n if (!hasApprovedTrade) {\n if (duty.PendingProposalsCount > 0) infos.push({\n label: 'Proposals',\n num: duty.PendingProposalsCount\n });\n if (duty.BookmarksCount > 0) infos.push({\n label: 'Bookmarks',\n num: duty.BookmarksCount\n }); // var totalBookmarks = (duty.bookmarks == undefined ? 0 : duty.bookmarks.length);\n // if (totalBookmarks > 0) infos.push({ label: 'Bookmarks', num: totalBookmarks.toString() });\n }\n } // else {\n // if (duty.TotalSharedDuties > 0) infos.push({ label: 'Total', num: duty.TotalSharedDuties.toString() });\n // //if (duty.unclaimedShared > 0) infos.push({ label: 'Unclaimed', num: duty.unclaimedShared.toString() });\n // }\n\n\n return infos;\n }\n\n function calendar(events) {\n $('#calendar').fullCalendar('destroy');\n $(\"#calendar\").fullCalendar({\n defaultView: getDefaultView(),\n defaultDate: defaultBucketDate,\n firstDay: 1,\n lang: 'en',\n editable: false,\n draggable: false,\n selectable: false,\n selectHelper: false,\n unselectAuto: false,\n disableResizing: false,\n droppable: false,\n fixedWeekCount: false,\n nextDayThreshold: \"00:00:00\",\n header: {\n left: 'title',\n center: '',\n right: 'month,listMonth today prev,next'\n },\n timeFormat: 'HH:mm',\n displayEventEnd: true,\n events: events,\n eventOrder: \"sortOrder\",\n eventRender: function eventRender(event, element, icon) {\n element.find('.fc-title').prepend(\"
\");\n\n if ($('#calendar').fullCalendar('getView').type === 'listMonth') {\n element.find('.fc-list-item-title').addClass('listview-icon');\n $.each(event.className, function (index, icon) {\n element.addClass(event.listViewColor);\n });\n $.each(event.icons, function (index, icon) {\n element.find('.listview-icon').prepend(\" \");\n });\n\n if (event.otherInfos != null && event.otherInfos.length > 0) {\n $.each(event.otherInfos, function (index, info) {\n if (info.label == 'Proposals') element.find('.fc-list-item-title').append(\"\" + info.num + \"\");\n });\n }\n } else {\n if (event.icons != null && event.icons.length > 0) {\n element.find('.fc-title').prepend(\"\");\n $.each(event.icons, function (index, icon) {\n element.find('.calendar-icon').append(\" \");\n });\n }\n\n if (event.otherInfos != null && event.otherInfos.length > 0) {\n $.each(event.otherInfos, function (index, info) {\n element.find('.fc-title').append(\"
\" + info.label + \": \" + info.num + \"
\");\n element.find('.fc-list-item-title').add(\"\" + info.num + \"\");\n });\n }\n }\n },\n eventResize: function eventResize(event, delta, revertFunc) {\n changeView(detectMobile(), '#calendar');\n },\n dayRender: function dayRender(date, cell) {},\n // dayClick: function(date, jsEvent, view) {\n // $timeout(function(){ gotoDayBucketView(date); })\n // },\n eventClick: function eventClick(calEvent, jsEvent, view) {\n if (calEvent.shareable == true && calEvent.isOwnDuty && (!calEvent.isApproved || calEvent.isOwnApproved)) {\n $timeout(function () {\n gotoDayBucketView(calEvent._id);\n });\n } else if (calEvent.shareable == false && calEvent.isOwnDuty) {\n if (!calEvent.isApproved) {\n //don't allow click for approved duty\n $timeout(function () {\n unableShare();\n });\n }\n }\n },\n height: 'auto'\n });\n $('.fc-listMonth-button').click(function () {\n SettingsMain.setCalendarViewStyle('listMonth');\n });\n $('.fc-month-button').click(function () {\n SettingsMain.setCalendarViewStyle('month');\n });\n\n if (selectedDate != null && selectedDate != undefined) {\n $(\"#calendar\").fullCalendar('gotoDate', selectedDate);\n }\n }\n\n function getDefaultView() {\n var calendarStyle = SettingsMain.getCalendarViewStyle();\n\n if (calendarStyle == null) {\n calendarStyle = detectMobile() ? \"listMonth\" : \"month\";\n }\n\n return calendarStyle;\n }\n\n function detectMobile() {\n var isMobile = window.innerWidth <= 800 && window.innerHeight <= 735;\n return isMobile;\n }\n /**\r\n * Redirects to bucket calendar day \r\n * @memberof BucketCtrl\r\n */\n\n\n function gotoDayBucketView(dutyId) {\n $location.path('/bucketDay/' + dutyId);\n }\n }\n\n function unableShare() {\n bootbox.dialog({\n message: \"
You can't share this duty, please try another shareable duty.
\",\n title: \"Warning\",\n buttons: {\n cancel: {\n label: \"Close\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n\n function progressBarBox(isOpen) {\n if (isOpen) {\n bootbox.dialog({\n closeButton: false,\n message: '
Please wait...
' //title: \"Please wait...\"\n\n });\n } else {\n bootbox.hideAll();\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('BucketFactory', BucketFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name BucketFactory\r\n * @description \r\n * Get Duties from API \r\n * @ngInject\r\n */\n\n function BucketFactory(GenericService, $http, $q, apiUrl, LogService) {\n /**\r\n * Initialize Bucket\r\n * @memberof BucketFactory\r\n */\n var service = {\n getDutyObject: getDutyObject,\n getDutyById: getDutyById,\n shareDuty: shareDuty,\n acknowledgeProposal: acknowledgeProposal,\n fetchProposal: fetchProposal,\n createProposal: createProposal,\n evaluateProposal: evaluateProposal,\n undoProposalStatus: undoProposalStatus,\n fetchSharedProposal: fetchSharedProposal\n };\n /**\r\n * Gets Bucket Calendar object\r\n * @memberof BucketFactory\r\n * @param {function} callback \r\n */\n\n function getDutyObject(callback) {\n return $http.get(apiUrl + '/bucket/', {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n /**\r\n * Gets duty object and shared duties object for the BucketDay View\r\n * @memberof BucketFactory\r\n * @param {number} dutyId \r\n * @param {function} callback \r\n */\n\n\n function getDutyById(dutyId, callback) {\n return $http.get(apiUrl + '/bucket/GetBucketDuty/' + dutyId, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n /**\r\n * Shares/Unshares duty\r\n * @memberof BucketFactory\r\n * @param {object} duty \r\n * @param {function} callback \r\n * @param {function} errorCallback \r\n */\n\n\n function shareDuty(duty, callback, errorCallback) {\n //todo remove when api became correct\n var dutyMinified = {\n Id: duty.Id,\n Shareable: duty.Shareable,\n Shared: duty.Shared,\n Comments: duty.Comments,\n CrewInformation: {\n Email: null,\n Phone: null,\n Comments: null\n }\n };\n return $http.post(apiUrl + '/bucket/ShareDuty/', dutyMinified, {\n 'Content-Type': 'application/json'\n }).then(callback)[\"catch\"](errorCallback);\n }\n /**\r\n * Makes proposal acknowledged \r\n * @memberof BucketFactory\r\n * @param {number} proposalId \r\n * @param {function} callback \r\n */\n\n\n function acknowledgeProposal(proposalId, callback) {\n return $http.get(apiUrl + '/bucket/AcknowledgeProposal?proposalId=' + proposalId, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n /**\r\n * Fetches proposal info \r\n * @memberof BucketFactory\r\n * @param {number} dutyId \r\n * @param {function} callback \r\n * @returns {object} - Promise containing Proposed and Requested duties alongside Crew and Route details for each one\r\n */\n\n\n function fetchProposal(dutyId, callback) {\n return $http.get(apiUrl + '/bucket/FetchProposal?id=' + dutyId, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n /**\r\n * Fetches shared proposal info\r\n * @param {number} dutyId \r\n * @param {number} sharedDutyId \r\n * @param {function} callback\r\n * @returns {object} - Promise containing Proposed and Requested duties alongside Crew and Route details for each one\r\n */\n\n\n function fetchSharedProposal(dutyId, sharedDutyId, callback) {\n return $http.get(apiUrl + '/bucket/FetchSharedProposal?dutyId=' + dutyId + '&sharedDutyId=' + sharedDutyId, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n /**\r\n * Creates/Sends Proposal\r\n * @memberof BucketFactory\r\n * @param {object} proposal - Containing proposedDutiesIdList and requestedDutiesIdList\r\n * @param {function} callback\r\n * @returns {object} - Promise containing updated proposal \r\n */\n\n\n function createProposal(proposal, callback) {\n return $http.post(apiUrl + '/bucket/CreateProposal', proposal, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n /**\r\n * Approves/Rejects proposal\r\n * @memberof BucketFactory\r\n * @param {object} proposal - Containing Id and isApproved\r\n * @param {function} callback\r\n * @returns {object} - Promise containing updated proposal \r\n */\n\n\n function evaluateProposal(proposal, callback) {\n return $http.put(apiUrl + '/bucket/EvaluateProposal/' + proposal.Id, proposal.isApproved, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n /**\r\n * Reverts proposal to previous status\r\n * @memberof BucketFactory\r\n * @param {number} proposalId \r\n * @param {function} callback \r\n * @returns {object} - Promise containing updated proposal\r\n */\n\n\n function undoProposalStatus(proposalId, callback) {\n return $http.put(apiUrl + '/bucket/UndoProposalStatus/' + proposalId, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('BucketDayCtrl', BucketDayCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name BucketDayCtrl\r\n * @description \r\n * Shows the Bucket Day informations\r\n * @ngInject\r\n */\n\n function BucketDayCtrl($scope, BucketFactory, $routeParams, $location, $uibModal, UserFactory, SettingsMain, $timeout) {\n $scope.isSharedLate = false;\n $scope.selectedStates = \"Shared, Pending\";\n /**\r\n * Checks if duty wont be approved in time because of the weekend \r\n * @memberof BucketDayCtrl\r\n */\n\n function checkLateShare() {\n var today = new Date();\n var dutyDay = new Date($scope.duty.DutyBegin); // how many days until duty date\n\n var trimmedToday = new Date(today);\n var trimmedDutyDay = new Date(dutyDay);\n var diffDays = Date.DifferenceInDays(trimmedToday.trimTime(), trimmedDutyDay.trimTime()); //friday saturday sunday\n\n var fss = [5, 6, 0]; //saturday sunday monday\n\n var ssm = [6, 0, 1]; // today is Fr,Sa,Su AND duty on Sa,Su,Mo AND same weekend\n\n if (fss.contains(today.getDay()) && ssm.contains(dutyDay.getDay()) && diffDays < 4) {\n //friday before 14:00 is not a late share\n if (!(today.getDay() == 5 && today.getUTCHours() < 14)) $scope.isSharedLate = true;\n }\n }\n\n $scope.currentDutyId = dutyId;\n $scope.initialized = false;\n $scope.displayMessage = displayMessage;\n $scope.confirmUnshare = confirmUnshare;\n $scope.shareDuty = shareDuty;\n $scope.isLoading = false;\n var dutyId = $routeParams.dutyId;\n $scope.currentDutyId = dutyId;\n var user = UserFactory.getUser();\n $scope.activeTab = 0;\n $scope.duty = null;\n $scope.Duties = [];\n $scope.proposals = [];\n $scope.toggle = {\n Accepted: true,\n Rejected: false,\n Pending: true,\n Bookmarks: true\n };\n $scope.getProposalBorderStyle = getProposalBorderStyle;\n\n function getProposalBorderStyle(proposal) {\n var textclass = \"\";\n\n if (proposal.Status == \"Pending\" && proposal.State == 'Out') {\n textclass = \"border-left-light-blue\";\n } else if (proposal.Status == \"Rejected\" || proposal.Status == \"RejectedBySTP\") {\n textclass = \"border-left-red\";\n } else if (proposal.Status == \"Pending\" && proposal.State == 'In') {\n textclass = \"border-left-orange\";\n } else if (proposal.Status == \"Approved\" || proposal.Status == \"ApprovedBySTP\") {\n textclass = \"border-left-green\";\n } else if (proposal.Status == \"Shared\") {\n textclass = \"border-left-blue-gray\";\n }\n\n return textclass;\n }\n\n $scope.logged_user_info = user.aimsId + ' - ' + user.name;\n $scope.hasTimeChange = false;\n $scope.approvedDuty = null;\n $scope.showMobileProposalCriteria = false;\n $scope.filterProposal = filterProposal;\n $scope.hasProposals = hasProposals;\n\n function hasProposals() {\n var value = false;\n\n if ($scope.duty && $scope.duty.Duties) {\n for (var i = 0; i < $scope.duty.Duties.length; i++) {\n if ($scope.duty.Duties[i].Id > 0) {\n value = true;\n break;\n }\n }\n\n if (!value && $scope.activeTab != 1) {\n $scope.activeTab = 1;\n }\n }\n\n return value;\n }\n\n function filterProposal(proposal) {\n var isShown = false; ///ng-if=\"proposal.Id >0 && filterProposal(proposal)\"\n\n if (proposal.Id > 0) {\n if (proposal.Status == \"Approved\" || proposal.Status == \"ApprovedBySTP\") {\n $scope.approvedDuty = true;\n if ($scope.toggle.Accepted) isShown = true;\n } else if (proposal.Status == \"Pending\" && $scope.toggle.Pending) {\n isShown = true;\n } else if ((proposal.Status == \"Rejected\" || proposal.Status == \"RejectedBySTP\") && ($scope.toggle.Rejected || !proposal.isAcknowledged)) {\n isShown = true;\n } else if (proposal.Status == \"Bookmarked\" && $scope.toggle.Bookmarks) {\n isShown = true;\n }\n }\n\n return isShown;\n }\n\n $scope.returnToBucket = returnToBucket;\n $scope.refresh = getData;\n getData();\n\n function getData() {\n $scope.isLoading = true;\n BucketFactory.getDutyById(dutyId, function (responseData) {\n $scope.initialized = true;\n $scope.isLoading = false;\n $scope.duty = responseData.data.data.duty;\n $scope.currentDutyDate = $scope.duty.DutyDateS;\n $scope.Duties = responseData.data.data.duty.Duties;\n $scope.totalItems = $scope.Duties.length;\n $scope.currentPage = 1;\n SettingsMain.setCalendarSelectedDate($scope.currentDutyDate);\n checkLateShare();\n initProposalsView();\n })[\"catch\"](function (error) {\n $scope.isLoading = false;\n console.error('Wrong AimsId', error.status, error.statusText);\n returnToBucket();\n });\n }\n\n function initProposalsView() {\n $scope.approvedDuty = false;\n\n for (var i = 0; i < $scope.duty.Duties.length; i++) {\n if ($scope.duty.Duties[i].Status == \"Approved\" || $scope.duty.Duties[i].Status == \"ApprovedBySTP\") {\n $scope.approvedDuty = true;\n }\n }\n }\n /**\r\n * Opens a dialog with information on a duty, \r\n * Depending on the duty type (in proposal, out proposal or shared by other in bucket) different options are displayed:\r\n * 1. In proposal\r\n * - Approve (available when in proposal not reviewed, will set status to Approved)\r\n * - Reject (available when in proposal not reviewed, will set status to Rejected)\r\n * - Reset (available when in proposal has been reviewed, will set status to Pending)\r\n * - Close (available always, just closes dialog, no action performed)\r\n * 2. Out proposal\r\n * - Remove (available when out proposal not reviewed, will remove request from duty)\r\n * - Close (available always, just closes dialog, no action performed)\r\n * 3. Shared in bucket\r\n * - Request (available always, will send a request for duty, will be added in out proposals)\r\n * - Close (available always, just closes dialog, no action performed)\r\n * @memberof BucketCtrl\r\n */\n\n /**\r\n * Prompts user to confirm sharing duty, if user agrees then the duty dialog will open \r\n * @memberof BucketCtrl\r\n */\n\n\n function shareDuty(_duty) {\n //if (confirm('You are about to share into global bucket the selected duty. Do you wish to continue?')) {\n _duty.fromShareBtn = true;\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgDuty.html',\n controller: 'BucketModalCtrl',\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n duty: function duty() {\n return _duty;\n },\n currentDutyId: function currentDutyId() {\n return dutyId;\n }\n }\n });\n modalInstance.result.then(function (refresh) {\n if (refresh) {\n getData();\n }\n }); //}\n }\n /**\r\n * Prompts user to confirm removing duty from shared bucket, if user agrees then all proposal for the duty will be removed (will be displayed as N/A to other users) \r\n * @memberof BucketCtrl\r\n */\n\n\n function confirmUnshare() {\n bootbox.dialog({\n message: \"Please confirm that you wish to Un-share your duty.

\",\n title: \"Unshare\",\n buttons: {\n confirm: {\n label: ' Confirm',\n className: \"btn-warning\",\n callback: function callback() {\n BucketFactory.shareDuty($scope.duty, function (responseData) {\n $scope.responseText = responseData.data.data;\n getData();\n });\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n /**\r\n * Redirects to bucket' calendar\r\n * @memberof BucketCtrl\r\n */\n\n\n function returnToBucket() {\n SettingsMain.setEditingPage(null);\n $location.path(\"/bucket/\");\n }\n /**\r\n * Redirects to flights' calendar\r\n * @memberof BucketCtrl\r\n */\n\n\n function gotoFlightsCalendar() {\n SettingsMain.setEditingPage(null);\n $location.path(\"/\");\n } //Pagination\n\n\n $scope.pageOptions = [{\n name: '5',\n value: '5'\n }, {\n name: '8',\n value: '8'\n }, {\n name: '15',\n value: '15'\n }, {\n name: '30',\n value: '30'\n }, {\n name: '50',\n value: '50'\n }];\n $scope.viewby = $scope.pageOptions[1].value;\n $scope.currentPage = 1;\n $scope.itemsPerPage = $scope.viewby;\n $scope.maxSize = 5; //Number of pager buttons to show\n\n $scope.setPage = setPage;\n $scope.setItemsPerPage = setItemsPerPage;\n /**\r\n * Set pagination page number\r\n * @memberof BucketDayCtrl\r\n * @param {number} pageNo list page number\r\n */\n\n function setPage(pageNo) {\n $scope.currentPage = pageNo;\n }\n /**\r\n * Set items per page \r\n * @memberof BucketDayCtrl\r\n * @param {number} num the Number of items to show per page\r\n */\n\n\n function setItemsPerPage(num) {\n $scope.itemsPerPage = num;\n $scope.currentPage = 1; //reset to first page\n }\n\n function displayMessage(message, hasErrors) {\n $scope.showResponse = true;\n $scope.responseText = message;\n $scope.responseHasErrors = hasErrors;\n $timeout(function () {\n if (!hasErrors) {\n $scope.showResponse = false;\n }\n }, 1000);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('BucketModalCtrl', BucketModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name BucketModalCtrl\r\n * @description \r\n * Shows Share/Unshare Modal \r\n * @ngInject\r\n */\n\n function BucketModalCtrl($scope, $timeout, $uibModalInstance, duty, currentDutyId, BucketFactory) {\n $scope.duty = duty;\n $scope.currentDutyId = currentDutyId;\n $scope.closeDuty = closeDuty;\n $scope.shareDuty = shareDuty;\n $scope.responseText = null;\n $scope.responseHasErrors = null;\n $scope.submitted = false;\n /**\r\n * Close the modal\r\n * @memberof BucketModalCtrl\r\n */\n\n function closeDuty(refresh) {\n $uibModalInstance.close(refresh);\n }\n /**\r\n * Adds/Removes duty to/from global bucket\r\n * @memberof BucketModalCtrl\r\n */\n\n\n function shareDuty() {\n $scope.submitted = true;\n duty.Comments = $scope.duty.Comments;\n BucketFactory.shareDuty(duty, function (responseData) {\n displayMessage(\"Duty shared.\", false);\n $timeout(function () {\n closeDuty(true);\n }, 5000);\n }, function () {\n displayMessage(\"Failed to share duty.\", true);\n });\n }\n /**\r\n * Displays message when share/unshare \r\n * @memberof BucketModalCtrl\r\n * @param {string} message \r\n * @param {boolean} hasErrors \r\n */\n\n\n function displayMessage(message, hasErrors) {\n $scope.responseText = message;\n $scope.responseHasErrors = hasErrors;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('proposal', proposal);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name proposal\r\n * @restrict E\r\n * @description\r\n * Implementation of proposal\r\n * Initialize the proposal element of bucket\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function proposal(BucketFactory, $uibModal, $filter) {\n function link(scope, element, attrs) {\n scope.isOpen = false;\n scope.successful = false;\n scope.error = false;\n scope.proposal.createDisabled = false;\n scope.duty = scope.proposal.Duty;\n scope.loading = false;\n scope.errorMessage = null;\n scope.ProposedDuties = new Array();\n scope.RequestedDuties = new Array();\n scope.AllDuties = new Array();\n scope.fetch = fetchInformation;\n scope.viewInfoModal = viewInfoModal;\n scope.createProposal = createProposal;\n scope.evaluateProposal = evaluateProposal;\n scope.undoProposalStatus = undoProposalStatus;\n scope.acknowledgeProposal = acknowledgeProposal;\n scope.confirmCreateProposal = confirmCreateProposal;\n scope.getFirstInfoIcon = getFirstInfoIcon;\n scope.getSecondInfoIcon = getSecondInfoIcon;\n scope.hasSecondInfoIcon = hasSecondInfoIcon;\n scope.getTextColor = getTextColor;\n scope.getFirstActionIcon = getFirstActionIcon;\n scope.hasFirstActionIcon = hasFirstActionIcon;\n scope.getSecondActionIcon = getSecondActionIcon;\n scope.hasSecondActionIcon = hasSecondActionIcon;\n scope.getFetchIcon = getFetchIcon;\n scope.getInfoMessage = getInfoMessage;\n scope.firstAction = firstAction;\n scope.secondaryAction = secondaryAction;\n scope.showEndDate = showEndDate;\n scope.showTime = showTime;\n\n if (scope.duty.Comments && scope.duty.Comments != \"\") {\n scope.dutyCommentElipsis = dutyCommentElipsis(110);\n scope.showFullComment = false;\n }\n\n scope.toggleFullCommentVisibility = toggleFullCommentVisibility;\n /**\r\n * Toggles proposal comment\r\n * @memberof proposal\r\n */\n\n function toggleFullCommentVisibility() {\n scope.showFullComment = !scope.showFullComment;\n }\n /**\r\n * Shows only the first charNo characters of the comment\r\n * @memberof proposal\r\n * @param {number} charNo \r\n */\n\n\n function dutyCommentElipsis(charNo) {\n var comments = scope.duty.Comments;\n\n if (scope.duty.Comments.length > charNo) {\n comments = scope.duty.Comments.substring(0, charNo) + \"...\";\n }\n\n return comments;\n }\n /**\r\n * Updates proposal when a change occurs (create, evaluate or undo)\r\n * @memberof proposal\r\n * @param {object} newProp - The updated proposal \r\n */\n\n\n function updateProposal(newProp) {\n if (newProp) {\n scope.proposal.Status = newProp.Status;\n scope.proposal.State = newProp.State;\n scope.proposal.Id = newProp.Id;\n scope.proposal.isAcknowledged = newProp.isAcknowledged;\n }\n }\n /**\r\n * Fetches proposal info (Proposed and Requested duties alongside Crew and Route details for each one) \r\n * @memberof proposal\r\n */\n\n\n function fetchInformation() {\n if (!(scope.actionDisabled && scope.proposal.Status == 'Shared')) {\n if (!(scope.proposal.AllDuties && scope.proposal.AllDuties.length > 0)) {\n scope.loading = true;\n\n if (scope.proposal.Status == \"Shared\" && !scope.actionDisabled) {\n BucketFactory.fetchSharedProposal(scope.currentDutyId, scope.duty.Id, insertInformation)[\"catch\"](errorCall);\n } else {\n BucketFactory.fetchProposal(scope.proposal.Id, insertInformation)[\"catch\"](errorCall);\n }\n } else {\n scope.isOpen = !scope.isOpen; //collapse\n }\n }\n }\n /**\r\n * Handles error from fetchSharedProposal() and fetchProposal() \r\n * @memberof proposal\r\n */\n\n\n function errorCall() {\n scope.isOpen = false;\n scope.loading = false;\n displayMessage(\"Failed to fetch information.\", true);\n }\n /**\r\n * Callback for handling the successful response of fetchSharedProposal() and fetchProposal()\r\n * @memberof proposal\r\n * @param {object} data \r\n */\n\n\n function insertInformation(data) {\n var success = data.data.success;\n var errorMessage = data.data.errorMessage; //always show duties even if success is false\n\n if (data.data.data.duty) {\n var ProposedDuties = data.data.data.duty.ProposedDuties;\n var RequestedDuties = data.data.data.duty.RequestedDuties;\n scope.proposal.HasMultiDuties = data.data.data.duty.HasMultiDuties;\n ProposedDuties = $filter('orderBy')(ProposedDuties, 'DutyDate');\n RequestedDuties = $filter('orderBy')(RequestedDuties, 'DutyDate');\n\n if (ProposedDuties && RequestedDuties) {\n scope.proposal.AllDuties = [];\n var tableMaxRowLength = ProposedDuties.length > RequestedDuties.length ? ProposedDuties.length : RequestedDuties.length;\n\n for (var i = 0; i < tableMaxRowLength; i++) {\n if (scope.proposal.Status == \"Shared\" || scope.proposal.State == \"Out\") {\n var matchedDuty = {\n Proposed: ProposedDuties[i],\n //you give\n Requested: RequestedDuties[i] //you take\n\n };\n } else {\n //scope.proposal.State == \"In\"\n var matchedDuty = {\n Proposed: RequestedDuties[i],\n //you give\n Requested: ProposedDuties[i] //you take\n\n };\n }\n\n scope.proposal.AllDuties.push(matchedDuty);\n }\n\n scope.proposal.ProposedDuties = ProposedDuties;\n scope.proposal.RequestedDuties = RequestedDuties;\n scope.isOpen = true;\n }\n }\n\n if (!success) {\n //if not enough rest time\n //if no available combinations\n scope.proposal.createDisabled = true;\n } else {\n scope.proposal.createDisabled = false;\n } //always show errorMessage even if success is true\n\n\n if (errorMessage && errorMessage.length > 0) {\n displayMessage(errorMessage, true);\n } else {\n scope.errorMessage = null;\n }\n\n scope.loading = false;\n }\n /**\r\n * Opens modal for a specific duty in the table - Shows route and crew info \r\n * @memberof proposal\r\n * @param {number} id \r\n */\n\n\n function viewInfoModal(id) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgProposalInfo.html',\n controller: 'ProposalInfoModalCtr',\n size: 'lg',\n resolve: {\n ProposedDuties: function ProposedDuties() {\n return scope.proposal.ProposedDuties;\n },\n RequestedDuties: function RequestedDuties() {\n return scope.proposal.RequestedDuties;\n },\n Id: function Id() {\n return id;\n },\n Status: function Status() {\n return scope.proposal.Status;\n },\n State: function State() {\n return scope.proposal.State;\n }\n }\n });\n }\n /**\r\n * Creates/Sends proposal\r\n * @memberof proposal\r\n */\n\n\n function createProposal() {\n var proposedDutiesIdList = [];\n var requestedDutiesIdList = [];\n angular.forEach(scope.proposal.ProposedDuties, function (duty) {\n proposedDutiesIdList.push(duty.Id);\n });\n angular.forEach(scope.proposal.RequestedDuties, function (duty) {\n requestedDutiesIdList.push(duty.Id);\n }); //request body\n\n var proposal = {\n 'proposedDutiesIdList': proposedDutiesIdList,\n 'requestedDutiesIdList': requestedDutiesIdList\n };\n scope.loading = true;\n BucketFactory.createProposal(proposal, function (responseData) {\n displayMessage(\"Proposal has been sent\", false);\n scope.loading = false;\n updateProposal(responseData.data.data);\n\n if (scope.proposal.HasMultiDuties) {\n scope.refresh(); //needed in order to hide other duty from same proposal\n }\n })[\"catch\"](function () {\n displayMessage(\"Failed to send proposal.\", true);\n scope.loading = false;\n });\n }\n /**\r\n * Approves/Rejects proposal\r\n * @memberof proposal\r\n * @param {boolean} isApproved\r\n */\n\n\n function evaluateProposal(isApproved) {\n var proposal = {};\n proposal.Id = scope.proposal.Id;\n proposal.isApproved = isApproved;\n var onSuccessMessage, onFailureMessage;\n\n if (isApproved) {\n proposal.Status = \"Approved\";\n var onSuccessMessage = \"Approved proposal.\";\n var onFailureMessage = \"Failed to approve proposal.\";\n } else {\n proposal.Status = \"Rejected\";\n var onSuccessMessage = \"Rejected proposal.\";\n var onFailureMessage = \"Failed to reject proposal.\";\n }\n\n scope.loading = true;\n BucketFactory.evaluateProposal(proposal).then(function (responseData) {\n var success = responseData.data.success;\n\n if (success) {\n var newProp = responseData.data.data;\n updateProposal(newProp);\n\n if (isApproved) {\n scope.refresh(); //needed in order to disable other proposals\n }\n\n displayMessage(onSuccessMessage, false);\n } else {\n displayMessage(onFailureMessage, true);\n }\n })[\"catch\"](function () {\n displayMessage(onFailureMessage, true);\n });\n scope.loading = false;\n }\n /**\r\n * Reverts proposal to previous status\r\n * @memberof proposal\r\n */\n\n\n function undoProposalStatus() {\n scope.loading = true;\n var proposal = {};\n proposal.Id = scope.proposal.Id;\n var onSuccessMessage, onFailureMessage;\n\n if (scope.proposal.Status == \"Approved\" || scope.proposal.Status == \"Rejected\" && scope.proposal.State == 'In') {\n var onSuccessMessage = \"Proposal has been reset.\";\n var onFailureMessage = \"Failed to reset proposal.\";\n } else {\n //(scope.proposal.Status == \"Pending\" && scope.proposal.State=='Out')\n var onSuccessMessage = \"Withdrew proposal.\";\n var onFailureMessage = \"Failed to withraw proposal.\";\n }\n\n BucketFactory.undoProposalStatus(proposal.Id).then(function (responseData) {\n var previousStatus = scope.proposal.Status;\n var HasMultiDuties = scope.proposal.HasMultiDuties;\n var newProp = responseData.data.data;\n displayMessage(onSuccessMessage, false);\n scope.loading = false;\n updateProposal(newProp);\n\n if (previousStatus == \"Approved\") {\n scope.refresh(); //needed in order to enable other proposals again \n } else if (previousStatus == \"Pending\" && HasMultiDuties) {\n scope.refresh(); //needed in order to show other duties from same proposal \n }\n })[\"catch\"](function () {\n scope.loading = false;\n displayMessage(onFailureMessage, true);\n });\n }\n /**\r\n * Displays error or success message\r\n * @memberof proposal\r\n * @param {string} message \r\n * @param {boolean} hasErrors \r\n */\n\n\n function displayMessage(message, hasErrors) {\n if (hasErrors) {\n scope.errorMessage = message;\n } else {\n scope.errorMessage = null;\n }\n }\n /**\r\n * Makes proposal acknowledged \r\n * Available when status is 'RejectedBySTP' or status is 'Rejected' and state is 'Out'\r\n * @memberof proposal\r\n */\n\n\n function acknowledgeProposal() {\n scope.loading = true;\n var proposalId = scope.proposal.Id;\n var onFailureMessage = \"Failed to acknowledge proposal.\";\n BucketFactory.acknowledgeProposal(proposalId).then(function (responseData) {\n scope.proposal.isAcknowledged = true;\n scope.loading = false;\n })[\"catch\"](function () {\n scope.loading = false;\n displayMessage(onFailureMessage, true);\n });\n }\n /**\r\n * Changes proposal's first info icon depending on its state and status\r\n * @memberof proposal\r\n * @returns {string} - Icon name\r\n */\n\n\n function getFirstInfoIcon() {\n var icon = \"\";\n\n if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out') {\n icon = \"fa-thumbs-up\";\n } else if (scope.proposal.Status == \"Rejected\") {\n icon = \"fa-thumbs-down\";\n } else if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In') {\n icon = \"fa-thumbs-o-up\";\n } else if (scope.proposal.Status == \"Shared\") {\n icon = \"fa-bitbucket\";\n } else if (scope.proposal.Status == \"Approved\") {\n icon = \"fa fa-handshake-o\";\n } else if (scope.proposal.Status == \"ApprovedBySTP\") {\n icon = \"fa-thumbs-up\";\n } else if (scope.proposal.Status == \"RejectedBySTP\") {\n icon = \"fa-thumbs-o-down\";\n }\n\n return icon;\n }\n /**\r\n * Changes proposal's second info icon depending on its state and status\r\n * @memberof proposal\r\n * @returns {string} - Icon name\r\n */\n\n\n function getSecondInfoIcon() {\n var icon = \"\";\n\n if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out') {\n icon = \"fa-clock-o text-gray\";\n } else if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In') {\n icon = \"fa-question-circle-o\";\n }\n\n return icon;\n }\n /**\r\n * Determines second info icon's visibility\r\n * @memberof proposal\r\n * @returns {boolean}\r\n */\n\n\n function hasSecondInfoIcon() {\n return scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In' || scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out';\n }\n /**\r\n * Changes column color depending on proposal's state and status\r\n * @memberof proposal\r\n * @returns {string} - Color's class\r\n */\n\n\n function getTextColor() {\n var textclass = \"\";\n\n if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out') {\n textclass = \"text-light-blue\";\n } else if (scope.proposal.Status == \"Rejected\") {\n textclass = \"text-red\";\n } else if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In') {\n textclass = \"text-orange\";\n } else if (scope.proposal.Status == \"Approved\") {\n textclass = \"text-green\";\n } else if (scope.proposal.Status == \"Shared\") {\n textclass = \"text-blue-gray\";\n } else if (scope.proposal.Status == \"ApprovedBySTP\") {\n textclass = \"text-green\";\n } else if (scope.proposal.Status == \"RejectedBySTP\") {\n textclass = \"text-red\";\n }\n\n return textclass;\n }\n /**\r\n * Changes proposal's first action icon depending on its state and status\r\n * @memberof proposal\r\n * @returns {string} - Icon name\r\n */\n\n\n function getFirstActionIcon() {\n var icon = \"\";\n\n if (scope.proposal.createDisabled) {\n icon = \"fa-ban text-red\"; //no action permitted\n } else if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out' || scope.proposal.Status == \"Approved\") {\n icon = \" fa-times text-gray \"; //undo\n } else if (scope.proposal.Status == \"Rejected\" && scope.proposal.State == \"In\") {\n icon = \" fa-times text-gray \"; //undo\n } else if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In' && !scope.actionDisabled) {\n icon = \"fa-thumbs-o-up text-green\"; //approve\n } else if (scope.proposal.Status == \"Shared\" && !scope.actionDisabled) {\n icon = \"fa-thumbs-o-up text-light-blue\"; //create\n }\n\n return icon;\n }\n /**\r\n * Changes proposal's fetch icon if create action is disabled \r\n * @memberof proposal\r\n * @returns {string} - Icon name\r\n */\n\n\n function getFetchIcon() {\n var icon = \"\";\n\n if (scope.proposal.createDisabled) {\n icon = \"fa-ban text-red\";\n } else {\n icon = \"fa-search\";\n }\n\n return icon;\n }\n /**\r\n * Changes proposal's second action icon depending on its state and status\r\n * @memberof proposal\r\n * @returns {string} - Icon name\r\n */\n\n\n function getSecondActionIcon() {\n var icon = \"\";\n\n if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In') {\n icon = \"fa-thumbs-o-down text-red\"; //reject\n }\n\n return icon;\n }\n /**\r\n * Determines first action icon's visibility\r\n * @memberof proposal\r\n * @returns {boolean}\r\n */\n\n\n function hasFirstActionIcon() {\n return !(scope.proposal.Status == \"ApprovedBySTP\" || scope.proposal.Status == \"RejectedBySTP\");\n }\n /**\r\n * Determines second action icon's visibility\r\n * @memberof proposal\r\n * @returns {boolean}\r\n */\n\n\n function hasSecondActionIcon() {\n return scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In' || scope.proposal.Status == \"Shared\";\n }\n /**\r\n * Returns info message depending on proposal's state and status\r\n * @memberof proposal\r\n * @returns {string} - Message\r\n */\n\n\n function getInfoMessage() {\n var text = \"\";\n\n if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out') {\n text = \"your proposal is pending\";\n } else if (scope.proposal.Status == \"Rejected\" && scope.proposal.State == 'Out') {\n text = \"your proposal has been rejected\";\n } else if (scope.proposal.Status == \"Rejected\" && scope.proposal.State == 'In') {\n text = \"you have rejected the proposal\";\n } else if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In') {\n text = \"your response is pending\";\n } else if (scope.proposal.Status == \"Approved\" && scope.proposal.State == 'In') {\n text = \"you have accepted the proposal. Your request is sent for approval\";\n } else if (scope.proposal.Status == \"Approved\" && scope.proposal.State == 'Out') {\n text = \"your proposal has been accepted! Your request is sent for approval\";\n } else if (scope.proposal.Status == \"ApprovedBySTP\") {\n text = \"your request has been approved!\";\n } else if (scope.proposal.Status == \"RejectedBySTP\") {\n text = \"your request has been rejected by STP\";\n }\n\n return text;\n }\n /**\r\n * Determines duty's endDate visibility\r\n * @memberof proposal\r\n * @returns {boolean}\r\n */\n\n\n function showEndDate(duty) {\n var show = false;\n var diffMin = Date.DifferenceInMinutes(duty.DutyBegin, duty.DutyEnd);\n var diffHours = diffMin / 60;\n\n if (diffHours >= 24) {\n //endDate will show if duty exceeds 24 hours\n show = true;\n }\n\n return show;\n }\n /**\r\n * Hides duty begin and end time if needed\r\n * @param {object} duty \r\n */\n\n\n function showTime(duty) {\n var show = true;\n var diffMin = Date.DifferenceInMinutes(duty.DutyBegin, duty.DutyEnd);\n\n if (!diffMin) {\n //Time will not show if duty lasts all day (ex. Day Off: 00:00 - 00:00)\n show = false;\n }\n\n return show;\n }\n /**\r\n * Chooses first icon's action depending on proposal's state and status\r\n * @memberof proposal\r\n */\n\n\n function firstAction() {\n if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out') {\n undoProposalStatus();\n } else if (scope.proposal.Status == \"Approved\") {\n confirmUndoApproved();\n } else if (scope.proposal.Status == \"Rejected\" && scope.proposal.State == 'In') {\n undoProposalStatus();\n } else if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In') {\n evaluateProposal(true); //approve\n } else if (scope.proposal.Status == \"Shared\" && !scope.proposal.createDisabled) {\n if (scope.errorMessage && scope.errorMessage.length > 0) {\n confirmCreateProposal(); //fetch success with errorMessage\n } else {\n createProposal();\n }\n }\n }\n /**\r\n * Chooses second icon's action depending on proposal's state and status\r\n * @memberof proposal\r\n */\n\n\n function secondaryAction() {\n if (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In') {\n evaluateProposal(false); // reject proposal\n }\n }\n /**\r\n * Opens confirmation modal when undo is requested on an approved proposal\r\n * @memberof proposal\r\n */\n\n\n function confirmUndoApproved() {\n bootbox.dialog({\n message: \"You are about to cancel your accepted proposal.

\",\n title: \"Caution!\",\n buttons: {\n confirm: {\n label: 'Confirm',\n className: \"btn-danger\",\n callback: function callback() {\n undoProposalStatus();\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n /**\r\n * Opens confirmation modal when create is requested on an alternate proposal\r\n * @memberof proposal\r\n */\n\n\n function confirmCreateProposal() {\n bootbox.dialog({\n message: \"Would you like to proceed with the alternate proposal?

\",\n title: \"Send request\",\n buttons: {\n confirm: {\n label: 'Confirm',\n className: \"btn-success\",\n callback: function callback() {\n createProposal();\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/bucket/proposal.tpl.html',\n scope: {\n proposal: '=',\n displayMessage: '&onDisplay',\n refresh: '&onRefresh',\n actionDisabled: '=',\n currentDutyDate: '=',\n currentDutyId: '=',\n sharedCount: '='\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('ProposalInfoModalCtr', ProposalInfoModalCtr);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ProposalInfoModalCtr\r\n * @description \r\n * Shows duty crew and route info\r\n * @ngInject\r\n */\n\n function ProposalInfoModalCtr($scope, $uibModalInstance, ProposedDuties, RequestedDuties, Id, Status, State) {\n $scope.RequestedDuties = RequestedDuties;\n $scope.ProposedDuties = ProposedDuties;\n $scope.cancel = cancel;\n $scope.next = next;\n $scope.previous = previous;\n var allDuties = []; //\"You give\" items are put first in list\n\n if (Status == \"Shared\" || State == \"Out\") {\n allDuties = ProposedDuties.concat(RequestedDuties);\n } else {\n //State == \"In\"\n allDuties = RequestedDuties.concat(ProposedDuties);\n }\n\n for (var i = 0; i < allDuties.length; i++) {\n if (allDuties[i].Id == Id) {\n $scope.currentPage = i + 1;\n break;\n }\n }\n\n $scope.allDuties = allDuties;\n /**\r\n * Moves to next duty\r\n * @memberof ProposalInfoModalCtr\r\n */\n\n function next() {\n if ($scope.currentPage != allDuties.length) $scope.currentPage++;\n }\n /**\r\n * Moves to previous duty\r\n * @memberof ProposalInfoModalCtr\r\n */\n\n\n function previous() {\n if ($scope.currentPage != 1) $scope.currentPage--;\n }\n /**\r\n * Closes modal\r\n * @memberof ProposalInfoModalCtr\r\n */\n\n\n function cancel() {\n $uibModalInstance.close('cancel');\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('AssessmentCtrl', AssessmentCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name AssessmentCtrl\r\n * @description \r\n * Manages the Cabin Crew Feedback View \r\n * @ngInject\r\n */\n\n function AssessmentCtrl($scope, $location, CrewAssessmentFactory, $routeParams, SettingsMain, orderByFilter, FlightFactory, $timeout) {\n var editingPage = SettingsMain.getEditingPage();\n var flightId = $routeParams.flightId;\n var minDate, maxDate, flightRouteString;\n SettingsMain.setEditingPage(\"assessment\");\n var text = \"\";\n\n if (flightId == \"temp\") {\n var crewAssessment = CrewAssessmentFactory.getTempAssessment();\n $scope.flight = FlightFactory.getFlightFromStorage(crewAssessment.FlightId);\n SettingsMain.setEditingPage(null);\n } else {\n $scope.flight = FlightFactory.getFlightFromStorage(flightId);\n var crewAssessment = CrewAssessmentFactory.getCrewAssessmentFromStorage($scope.flight.assessment.Id);\n }\n\n if (crewAssessment) {\n var flights = orderByFilter(crewAssessment.Flights, orderByDate, false);\n\n for (var i = 0; i < flights.length; i++) {\n if (i == 0) {\n minDate = flights[i].ScheduledDepartureDateUTC + \"T\" + flights[i].ScheduledDepartureTimeUTC;\n flightRouteString = flights[i].Departure;\n } else if (i == flights.length - 1) {\n maxDate = flights[i].ScheduledArrival;\n flightRouteString = flightRouteString + \"-\" + flights[i].Departure + \"-\" + flights[i].Arrival;\n } else {\n flightRouteString = flightRouteString + \"-\" + flights[i].Departure;\n }\n }\n\n var route = {\n Route: crewAssessment.Route,\n DutyDate: crewAssessment.DutyDate,\n MinDate: minDate,\n MaxDate: maxDate,\n FlightRoute: flightRouteString\n };\n\n for (var i = 0; i < crewAssessment.assessedBy.length; i++) {\n if (i > 0) {\n var assessed = ', ' + crewAssessment.assesedBy[i].Name;\n } else {\n var assessed = crewAssessment.assessedBy[i].Name;\n }\n\n text = text.concat(assessed);\n }\n\n $scope.isFirstOpen = true;\n $scope.assessment = crewAssessment;\n $scope.togglePanel = togglePanel;\n $scope.route = route;\n $scope.assessedBy = text;\n }\n\n $scope.clearRemarks = clearRemarks;\n $scope.avgValue = avgValue;\n $scope.updateValues = updateValues;\n $scope.IsCompleted = IsCompleted;\n $scope.IsSynched = IsSynched;\n $scope.assessments_not_completed = CrewAssessmentFactory.getCountOfUncompletedAssessments();\n $scope.saveClicked = saveClicked;\n $scope.saveDraftClicked = saveDraftClicked;\n $scope.assesmentCSSClass = assesmentCSSClass;\n $scope.assesmentIconClass = assesmentIconClass;\n $scope.isPanelOpen = false;\n $scope.discard = discard;\n $scope.infosaveaction = false;\n /**\r\n * Display a successful save message according to the save status \r\n * @memberof AssessmentCtrl\r\n * @param {string} state the state of the selected Cabin Crew Feedback\r\n */\n\n function infoSaveOperation(state) {\n if (state == 'Completed') {\n $scope.infosaveactiontype = state;\n $scope.infosaveaction = true;\n } else if (state == 'Draft') {\n $scope.infosaveactiontype = state;\n $scope.infosaveaction = true;\n } else if (state == 'discard') {\n $scope.infosaveactiontype = state;\n $scope.infosaveaction = true;\n }\n\n $timeout(function () {\n $scope.infosaveaction = false;\n }, 5000);\n }\n /**\r\n * Convers date string to JS object\r\n * @memberof AssessmentCtrl\r\n * @param {string} ScheduledArrival The string date of ScheduledArrival \r\n * @returns {Object} ScheduledArrival\r\n */\n\n\n function orderByDate(item) {\n var date = new Date(item.ScheduledArrival);\n return date;\n }\n /**\r\n * Clear Remarks\r\n * @memberof AssessmentCtrl\r\n * @param {string} item The Crew assessment Template question item \r\n */\n\n\n function clearRemarks(item) {\n // put preset comments\n if (item != null && item.ItemDescr) {\n item.ItemDescr = null;\n }\n\n if (item != null && item.Review) {\n item.Review = null;\n }\n }\n /**\r\n * Returns the avarage score of the questions.\r\n * @memberof AssessmentCtrl\r\n * @param {array} items The Crew assessment Template question items \r\n * @returns {number} retval\r\n */\n\n\n function avgValue(items) {\n var sum = 0;\n\n if (!items || items.length == 0) {\n return sum;\n }\n\n for (var i = 0; i < items.length; i++) {\n if (items[i]) {\n sum = sum + parseInt(items[i].ItemValue);\n }\n }\n\n var retval = sum / items.length ? (sum / items.length).toFixed(1) : '-';\n return retval;\n }\n /**\r\n * Updates the value for the selected crewmember for this Cabin Crew Feedback and update the temporary Cabin Crew Feedback\r\n * @memberof AssessmentCtrl \r\n * @param {object} crewMember The Crew member\r\n * @param {object} assessment The Crew assessment \r\n */\n\n\n function updateValues(crewMember, assessment) {\n crewMember.IsCompleted = crewMember.Review != null && crewMember.Review.trim().length > 0;\n CrewAssessmentFactory.saveTempAssessment(assessment, $scope.flight.FlightId);\n }\n /**\r\n * Evaluate if this Cabin Crew Feedback is valid and ready to send\r\n * @memberof AssessmentCtrl \r\n * @param {object} assessment The Crew assessment \r\n * @returns {boolean} isCompleted\r\n */\n\n\n function IsCompleted(crewAssessment) {\n var isCompleted = true;\n\n for (var j = 0; j < crewAssessment.CrewAssessmentMembers.length; j++) {\n if (!(crewAssessment.CrewAssessmentMembers[j].Review != null && crewAssessment.CrewAssessmentMembers[j].Review.trim().length > 0)) {\n if (!crewAssessment.CrewAssessmentMembers[j].IsExist && (crewAssessment.CrewAssessmentMembers[j].IsValid || crewAssessment.CrewAssessmentMembers[j].IsOverride)) {\n isCompleted = false;\n }\n }\n }\n\n return isCompleted;\n }\n /**\r\n * Evaluate if this Cabin Crew Feedback is synched\r\n * @memberof AssessmentCtrl \r\n * @param {object} assessment The Crew assessment \r\n * @returns {boolean} IsSynched\r\n */\n\n\n function IsSynched() {\n var IsSynched = false;\n\n if (crewAssessment.Status == \"Stored\") {\n IsSynched = true;\n }\n\n return IsSynched;\n }\n /**\r\n * Save the Cabin Crew Feedback\r\n * @memberof AssessmentCtrl \r\n * @param {object} assessment The Cabin Crew Feedback\r\n */\n\n\n function saveAssessment(assessment) {\n CrewAssessmentFactory.setCrewAssessmentToStorage(assessment);\n CrewAssessmentFactory.updateFlightsAssessment(assessment);\n CrewAssessmentFactory.updateCrewRouteAssessment(assessment);\n }\n /**\r\n * Save the Cabin Crew Feedback As Completed\r\n * @memberof AssessmentCtrl \r\n * @param {object} assessment The Cabin Crew Feedback\r\n */\n\n\n function saveClicked(assessment) {\n assessment.Status = 'Completed';\n saveAssessment(assessment);\n infoSaveOperation(assessment.Status);\n SettingsMain.setEditingPage(null);\n CrewAssessmentFactory.clearTempAssessment();\n $location.path('/flightinfo/' + $scope.flight.FlightId);\n }\n /**\r\n * Discard all the changes on the cabin crew feedback that are not saved\r\n * @memberof AssessmentCtrl \r\n */\n\n\n function discard() {\n SettingsMain.setEditingPage(null);\n $scope.assessment = CrewAssessmentFactory.getCrewAssessmentFromStorage($scope.flight.assessment.Id);\n infoSaveOperation('discard');\n }\n /**\r\n * Save the Cabin Crew Feedback As Draft\r\n * @memberof AssessmentCtrl \r\n * @param {object} assessment The Cabin Crew Feedback\r\n */\n\n\n function saveDraftClicked(assessment) {\n assessment.Status = 'Draft';\n saveAssessment(assessment);\n infoSaveOperation(assessment.Status);\n SettingsMain.setEditingPage(null);\n CrewAssessmentFactory.clearTempAssessment();\n }\n /**\r\n * Open and close the selected Panel\r\n * @memberof AssessmentCtrl \r\n * @param {number} panelId The panel's Id\r\n */\n\n\n function togglePanel(panelId) {\n $('#' + panelId).toggle();\n if (panelId == \"info-panel\") $scope.isPanelOpen = !$scope.isPanelOpen;\n }\n /**\r\n * The css class for the selected crew member\r\n * @memberof AssessmentCtrl \r\n * @param {Object} crewMember The assessed crew member\r\n * @returns {string} cssClass\r\n */\n\n\n function assesmentCSSClass(crewMember) {\n if (!crewMember.IsExist && crewMember.IsCompleted && (crewMember.IsValid || crewMember.IsOverride)) {\n return 'panel-blue';\n } else if (!crewMember.IsExist && !crewMember.IsCompleted && (crewMember.IsValid || crewMember.IsOverride)) {\n return 'panel-orange';\n } else if (!crewMember.IsExist && !crewMember.IsValid && !crewMember.IsOverride) {\n return 'panel-default';\n } else if (crewMember.IsExist) {\n return 'panel-green';\n }\n }\n /**\r\n * The icon for the selected crew member\r\n * @memberof AssessmentCtrl \r\n * @param {Object} crewMember The assessed crew member\r\n * @returns {string} iconClass\r\n */\n\n\n function assesmentIconClass(crewMember) {\n if (!crewMember.IsExist && crewMember.IsCompleted && (crewMember.IsValid || crewMember.IsOverride)) {\n return 'fa fa-check';\n } else if (!crewMember.IsExist && !crewMember.IsCompleted && (crewMember.IsValid || crewMember.IsOverride)) {\n return 'fa fa-pencil';\n } else if (!crewMember.IsExist && !crewMember.IsValid && !crewMember.IsOverride) {\n return 'fa fa-times';\n } else if (crewMember.IsExist) {\n return 'fa fa-floppy-o';\n }\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('AssessmentSyncResultFactory', AssessmentSyncResultFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AssessmentSyncResultFactory\r\n * @description \r\n * Add, Update, Delete and Get Cabin Crew Feedback Sync Results.\r\n * @ngInject\r\n */\n\n function AssessmentSyncResultFactory(GenericService) {\n /**\r\n * Initialize the CrewAssessment\r\n * @memberof AssessmentSyncResultFactory\r\n */\n function AssessmentSyncResult() {\n this.Route = null;\n this.DutyDate = null;\n this.message = null;\n this.success = null;\n }\n\n var objType = 'assessmentSyncResults';\n var objCallback = AssessmentSyncResult;\n var service = {\n getAssessmentSyncResultsFromStorage: getAssessmentSyncResultsFromStorage,\n setAssessmentSyncResultsToStorage: setAssessmentSyncResultsToStorage,\n getSuccesses: getSuccesses,\n getFailures: getFailures\n };\n /**\r\n * Get Assessment Sync Results\r\n * @memberof AssessmentSyncResultFactory\r\n * @returns {Array} AssessmentSyncResults \r\n */\n\n function getAssessmentSyncResultsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save Assessment Sync Results in Local Storage\r\n * @memberof AssessmentSyncResultFactory\r\n * @param {Array} AssessmentSyncResults A list of Assessment Sync Results\r\n */\n\n\n function setAssessmentSyncResultsToStorage(assessmentSyncResults) {\n GenericService.saveAll(assessmentSyncResults, objType, objCallback);\n }\n /**\r\n * Get Successfull Assessment Sync Results from Local Storage\r\n * @memberof AssessmentSyncResultFactory\r\n * @param {Array} AssessmentSyncResults A list of Assessment Sync Results\r\n * @returns {Array} AssessmentSyncResults \r\n */\n\n\n function getSuccesses(syncResults) {\n var result = 0;\n\n if (!syncResults) {\n return result;\n }\n\n for (var i = 0; i < syncResults.length; i++) {\n if (syncResults[i].success == true) {\n result = result + 1;\n }\n }\n\n return result;\n }\n /**\r\n * Get Failed Assessment Sync Results from Local Storage\r\n * @memberof AssessmentSyncResultFactory\r\n * @param {Array} AssessmentSyncResults A list of Assessment Sync Results\r\n * @returns {Array} AssessmentSyncResults \r\n */\n\n\n function getFailures(syncResults) {\n var result = 0;\n\n if (!syncResults) {\n return result;\n }\n\n for (var i = 0; i < syncResults.length; i++) {\n if (syncResults[i].success == false) {\n result = result + 1;\n }\n }\n\n return result;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CrewAssessmentFactory', CrewAssessmentFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewAssessmentFactory\r\n * @description \r\n * Add, Update, Delete and Get Cabin Crew Feedback.\r\n * @ngInject\r\n */\n\n function CrewAssessmentFactory(localStorageMD5Service, CrewAssessmentMemberFactory, FlightFactory, CrewAssessmentTemplateFactory, CabinReportLocalEditFactory, GenericService, CrewRouteFactory) {\n /**\r\n * Initialize the CrewAssessment\r\n * @memberof CrewAssessmentFactory\r\n */\n function CrewAssessment() {\n this.Id = null;\n this.UserId = null;\n this.Route = null;\n this.DutyDate = null;\n this.DutyDay = null;\n this.AcType = null;\n this.Status = 'Pending';\n this.IsExist = false;\n this.assessedBy = [];\n this.CrewAssessmentMembers = [];\n this.Flights = [];\n this.GetId = GetId;\n this.start = null;\n this.end = null;\n }\n\n var objType = 'crewAssessments';\n var objCallback = CrewAssessment;\n var service = {\n getCrewAssessmentsFromStorage: getCrewAssessmentsFromStorage,\n setCrewAssessmentsToStorage: setCrewAssessmentsToStorage,\n setCrewAssessmentToStorage: setCrewAssessmentToStorage,\n getCrewAssessmentFromStorage: getCrewAssessmentFromStorage,\n getCountOfUncompletedAssessments: getCountOfUncompletedAssessments,\n getCrewAssessmentByRoute: getCrewAssessmentByRoute,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n getNewCrewAssessment: getNewCrewAssessment,\n getTempAssessment: getTempAssessment,\n saveTempAssessment: saveTempAssessment,\n clearTempAssessment: clearTempAssessment,\n updateCrewMembers: updateCrewMembers,\n updateCrewAssessment: updateCrewAssessment,\n getAssesedCabinReports: getAssesedCabinReports,\n existsForRouteDutyDate: existsForRouteDutyDate,\n getAssementsReadyToSend: getAssementsReadyToSend,\n storeFlightsWithAssessments: storeFlightsWithAssessments,\n updateFlightsAssessment: updateFlightsAssessment,\n updateAssessmentFlights: updateAssessmentFlights,\n storeCrewRoutesWithAssessments: storeCrewRoutesWithAssessments,\n updateCrewRouteAssessment: updateCrewRouteAssessment\n }; //object functions\n\n /**\r\n * Overide default get Id\r\n * @memberof CrewAssessmentFactory\r\n * @returns {number} Id \r\n */\n\n function GetId() {\n return this.Id;\n } //factory functions\n\n /**\r\n * Get Crew Assessments\r\n * @memberof CrewAssessmentFactory\r\n * @returns {Array} crewAssesments \r\n */\n\n\n function getCrewAssessmentsFromStorage() {\n var lsItems = GenericService.list(objType, objCallback);\n var items = [];\n\n for (var i = 0; i < lsItems.length; i++) {\n if (lsItems[i]) {\n items.push(lsItems[i]);\n }\n }\n\n return items;\n }\n /**\r\n * Save Crew Assessments to storage\r\n * @memberof CrewAssessmentFactory\r\n * @param {Array} crewAssessments A list of Cabin Crew Feedbacks\r\n */\n\n\n function setCrewAssessmentsToStorage(crewAssessments) {\n GenericService.saveAll(crewAssessments, objType, objCallback);\n }\n /**\r\n * Save one Crew Assessment to storage\r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} crewAssessment A Cabin Crew Feedback\r\n */\n\n\n function setCrewAssessmentToStorage(crewAssessment) {\n GenericService.save(crewAssessment, objType, objCallback);\n }\n /**\r\n * Get a Crew Assessment from storage\r\n * @memberof CrewAssessmentFactory\r\n * @param {number} crewAssessmentId the Id of the selected Crew Assessment\r\n * @returns {Object} crewAssesment\r\n */\n\n\n function getCrewAssessmentFromStorage(crewAssessmentId) {\n return GenericService.get(crewAssessmentId, objType, objCallback);\n }\n /**\r\n * Get Count of Uncompleted Assessments \r\n * @memberof CrewAssessmentFactory\r\n * @returns {number} count\r\n */\n\n\n function getCountOfUncompletedAssessments() {\n var crewAssessments = getCrewAssessmentsFromStorage();\n var count = 0;\n if (crewAssessments == null) return 0;\n\n for (var i = 0; i < crewAssessments.length; i++) {\n if (!crewAssessments[i].IsExist && crewAssessments[i].Status != \"Completed\") {\n count++;\n }\n }\n\n return count;\n }\n\n ;\n /**\r\n * Get Crew Assessment By route and Duty Date\r\n * @memberof CrewAssessmentFactory\r\n * @param {string} Route the Route of the desired Crew Assessment\r\n * @param {string} DutyDate the Duty Date of the desired Crew Assessment\r\n * @returns {Object} crewAssesment\r\n */\n\n function getCrewAssessmentByRoute(Route, DutyDate) {\n var crewAssessments = getCrewAssessmentsFromStorage();\n if (crewAssessments == null) return null;\n var result = null;\n var arrayLength = crewAssessments.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (crewAssessments[i].Route == Route && crewAssessments[i].DutyDate == DutyDate) {\n result = crewAssessments[i];\n break;\n }\n }\n\n return result;\n }\n /**\r\n * Extend Object from the default CrewAssessment Object\r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} obj a crewAssesment\r\n * @returns {Object} crewAssesment\r\n */\n\n\n function fromObject(obj) {\n return GenericService.fromObject(obj, objCallback);\n }\n /**\r\n * Extend an array of Objects from the default CrewAssessment Object\r\n * @memberof CrewAssessmentFactory\r\n * @param {Array} objList an Array Of crewAssesments\r\n * @returns {Array} crewAssesments\r\n */\n\n\n function fromObjectList(objList) {\n return GenericService.fromObjectList(objList, objCallback);\n }\n /**\r\n * Initialize a new Crew Assessment from the default Constructor\r\n * @memberof CrewAssessmentFactory\r\n * @returns {Object} crewAssesment\r\n */\n\n\n function getNewCrewAssessment() {\n return GenericService.constructor(objCallback);\n }\n\n ;\n /**\r\n * Get the Temporary Assessment from the local storage\r\n * @memberof CrewAssessmentFactory\r\n * @returns {Object} crewAssesment\r\n */\n\n function getTempAssessment() {\n var crewAssessmentLocalEdit = localStorageMD5Service.get('crewAssessmentLocalEdit_TEMP');\n return fromObject(crewAssessmentLocalEdit);\n }\n\n ;\n /**\r\n * Save the Temporary Assessment to the local storage\r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} assessment a crewAssesment\r\n * @param {number} FlightId a crewAssesment\r\n */\n\n function saveTempAssessment(assessment, FlightId) {\n if (assessment) {\n assessment.FlightId = FlightId;\n localStorageMD5Service.remove('crewAssessmentLocalEdit_TEMP');\n localStorageMD5Service.set('crewAssessmentLocalEdit_TEMP', assessment);\n }\n }\n\n ;\n /**\r\n * Remove the Temporary Assessment of the local storage\r\n * @memberof CrewAssessmentFactory\r\n */\n\n function clearTempAssessment() {\n localStorageMD5Service.remove('crewAssessmentLocalEdit_TEMP');\n }\n\n ;\n /**\r\n * Update CrewMembers of the assessment based on CCMSPositions\r\n * @memberof CrewAssessmentFactory\r\n * @param {string} CCMSPositions the ccms Position of the Flight\r\n * @param {string} Route The route of the assessment\r\n * @param {string} DutyDate The duty date of the assessment\r\n */\n\n function updateCrewMembers(CCMSPositions, Route, DutyDate) {\n var assessment = getCrewAssessmentByRoute(Route, DutyDate);\n var crewAssessmentTemplate = CrewAssessmentTemplateFactory.getCrewAssessmentTemplateFromStorage();\n var routeFlights = FlightFactory.getFlightsByRoute(Route, DutyDate);\n var isChanged = false;\n\n if (CCMSPositions != null && assessment != null) {\n for (var i = 0; i < CCMSPositions.length; i++) {\n var isExists = false;\n\n for (var j = 0; j < assessment.CrewAssessmentMembers.length; j++) {\n if (CCMSPositions[i].CrewId == assessment.CrewAssessmentMembers[j].aimsId) {\n isExists = true;\n\n if (CCMSPositions[i].CCMS == \"N/A\") {\n var isValid = false;\n\n for (var h = 0; h < routeFlights.length; h++) {\n var localReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(routeFlights[h].FlightId);\n\n if (localReport != null) {\n for (var e = 0; e < localReport.CCMSCrewPositions.length; e++) {\n if (CCMSPositions[i].CrewId == localReport.CCMSCrewPositions[e].CrewId && localReport.CCMSCrewPositions[e].CCMS != \"N/A\") {\n isValid = true;\n break;\n }\n }\n }\n\n if (isValid) {\n break;\n }\n }\n\n if (assessment.CrewAssessmentMembers[j].IsValid != isValid) {\n isChanged = true;\n }\n\n assessment.CrewAssessmentMembers[j].IsValid = isValid;\n } else {\n if (!assessment.CrewAssessmentMembers[j].IsValid) {\n isChanged = true;\n }\n\n assessment.CrewAssessmentMembers[j].IsValid = true;\n }\n }\n }\n\n if (!isExists && CCMSPositions[i].IsManual) {\n var crewMember = CrewAssessmentMemberFactory.newMember();\n crewMember.aimsId = CCMSPositions[i].CrewId;\n crewMember.assessmentItems = crewAssessmentTemplate;\n crewMember.name = CCMSPositions[i].Name;\n crewMember.position = CCMSPositions[i].Position;\n crewMember.shortname = CCMSPositions[i].Initials;\n crewMember.IsManual = true;\n crewMember.IsCompleted = false;\n crewMember.IsValid = CCMSPositions[i].CCMS != \"N/A\";\n isChanged = true;\n assessment.CrewAssessmentMembers.push(crewMember);\n }\n }\n\n for (var i = 0; i < assessment.CrewAssessmentMembers.length; i++) {\n for (var h = 0; h < routeFlights.length; h++) {\n var localReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(routeFlights[h].FlightId);\n\n if (localReport != null) {\n isExists = false;\n\n for (var j = 0; j < localReport.CCMSCrewPositions.length; j++) {\n if (localReport.CCMSCrewPositions[j].CrewId == assessment.CrewAssessmentMembers[i].aimsId) {\n isExists = true;\n break;\n }\n }\n }\n }\n\n if (!isExists) {\n if (assessment.CrewAssessmentMembers[i].IsValid) {\n isChanged = true;\n }\n\n assessment.CrewAssessmentMembers[i].IsValid = false;\n }\n }\n\n if (isChanged && assessment.Status != \"Pending\") {\n assessment.Status = \"Draft\";\n var flights = FlightFactory.getFlightsFromStorage();\n\n for (var i = 0; i < flights.length; i++) {\n if (flights[i].assessment && flights[i].assessment.Id == assessment.Id) {\n flights[i].assessment.Status = assessment.Status;\n }\n }\n\n FlightFactory.setFlightsToStorage(flights);\n }\n\n setCrewAssessmentToStorage(assessment);\n }\n }\n /**\r\n * Update Assessment from the new Assessment from Sync\r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} assessment The assessment\r\n * @param {Object} newAssessment The new assessment\r\n */\n\n\n function updateCrewAssessment(assessment, newAssessment) {\n var crewAssessmentTemplate = CrewAssessmentTemplateFactory.getCrewAssessmentTemplateFromStorage();\n if (crewAssessmentTemplate == null) return assessment; // Load the flight\n\n var flights = FlightFactory.getFlightsByRoute(assessment.Route, assessment.DutyDate);\n if (flights == null) return assessment;\n assessment.Flights = [];\n assessment.AcType = flights[0].AcType;\n assessment = updateAssessmentFlights(assessment, flights);\n var isUpdated = false; // Flags to check member states\n\n var validCrewCount = 0; // Non-outdated and exists\n\n var outdatedCrewCount = 0; // Outdated\n\n var nonExistentCrewCount = 0; // Non-outdated but doesn't exist\n\n for (var i = 0; i < newAssessment.assessmentCrew.length; i++) {\n var isCreated = false; // Update flags based on crew member status\n\n if (newAssessment.assessmentCrew[i].IsOutdated && !newAssessment.assessmentCrew[i].IsExist) {\n outdatedCrewCount++;\n } else if (!newAssessment.assessmentCrew[i].IsExist) {\n nonExistentCrewCount++;\n } else {\n validCrewCount++;\n }\n\n for (var l = 0; l < assessment.CrewAssessmentMembers.length; l++) {\n if (newAssessment.assessmentCrew[i].CrewAimsId == assessment.CrewAssessmentMembers[l].aimsId || newAssessment.assessmentCrew[i].CrewId == assessment.CrewAssessmentMembers[l].Id) {\n assessment.CrewAssessmentMembers[l].aimsId = newAssessment.assessmentCrew[i].CrewAimsId;\n assessment.CrewAssessmentMembers[l].id = newAssessment.assessmentCrew[i].CrewId;\n assessment.CrewAssessmentMembers[l].name = newAssessment.assessmentCrew[i].Name;\n assessment.CrewAssessmentMembers[l].IsValid = true;\n assessment.CrewAssessmentMembers[l].IsOutdated = newAssessment.assessmentCrew[i].IsOutdated;\n assessment.CrewAssessmentMembers[l].EndPeriod = newAssessment.assessmentCrew[i].EndPeriod;\n var newAssessmentItems = [];\n\n for (var j = 0; j < crewAssessmentTemplate.length; j++) {\n var question = {\n Id: crewAssessmentTemplate[j].Id,\n Description: crewAssessmentTemplate[j].Description,\n Label: crewAssessmentTemplate[j].Label,\n OrderNo: crewAssessmentTemplate[j].OrderNo,\n ItemValue: crewAssessmentTemplate[j].ItemValue,\n ItemDescr: null\n };\n\n if (assessment.CrewAssessmentMembers[l].assessmentItems) {\n for (var h = 0; h < assessment.CrewAssessmentMembers[l].assessmentItems.length; h++) {\n if (crewAssessmentTemplate[j].Id == assessment.CrewAssessmentMembers[l].assessmentItems[h].Id) {\n question.ItemValue = assessment.CrewAssessmentMembers[l].assessmentItems[h].ItemValue;\n question.ItemDescr = assessment.CrewAssessmentMembers[l].assessmentItems[h].ItemDescr;\n }\n }\n }\n\n newAssessmentItems.push(question);\n }\n\n assessment.CrewAssessmentMembers[l].assessmentItems = newAssessmentItems;\n\n if (assessment.CrewAssessmentMembers[l].IsExist != newAssessment.assessmentCrew[i].IsExist) {\n assessment.CrewAssessmentMembers[l].IsExist = newAssessment.assessmentCrew[i].IsExist;\n isUpdated = true;\n }\n\n isCreated = true;\n break;\n }\n }\n\n if (!isCreated) {\n var crewMember = CrewAssessmentMemberFactory.newMember();\n crewMember.aimsId = newAssessment.assessmentCrew[i].CrewAimsId;\n crewMember.id = newAssessment.assessmentCrew[i].CrewId;\n crewMember.assessmentItems = crewAssessmentTemplate;\n crewMember.name = newAssessment.assessmentCrew[i].Name;\n crewMember.IsCompleted = false;\n crewMember.IsValid = true;\n crewMember.IsExist = newAssessment.assessmentCrew[i].IsExist;\n crewMember.IsOutdated = newAssessment.assessmentCrew[i].IsOutdated;\n crewMember.EndPeriod = newAssessment.assessmentCrew[i].EndPeriod;\n assessment.CrewAssessmentMembers.push(crewMember);\n isUpdated = true;\n }\n }\n\n for (var l = 0; l < assessment.CrewAssessmentMembers.length; l++) {\n var isExists = false;\n\n for (var i = 0; i < newAssessment.assessmentCrew.length; i++) {\n if (newAssessment.assessmentCrew[i].CrewAimsId == assessment.CrewAssessmentMembers[l].aimsId || newAssessment.assessmentCrew[i].CrewId == assessment.CrewAssessmentMembers[l].Id) {\n isExists = true;\n break;\n }\n }\n\n if (!isExists && !assessment.CrewAssessmentMembers[l].IsManual) {\n assessment.CrewAssessmentMembers.splice(l, 1);\n l--; // Adjust index after removal\n\n isUpdated = true;\n }\n } // Update the Status based on the flags\n\n\n if (validCrewCount > 0) {\n // If there's at least one valid (non-outdated and existing) crew member\n assessment.Status = \"Stored\";\n } else if (outdatedCrewCount > 0 && nonExistentCrewCount === 0) {\n // All members are outdated\n assessment.Status = \"Outdated\";\n } else if (nonExistentCrewCount > 0) {\n // If there are non-outdated but non-existent members\n assessment.Status = \"Pending\";\n } else if (isUpdated && assessment.Status == \"Stored\") {\n // If there were updates and it was stored before, downgrade to Draft\n assessment.Status = \"Draft\";\n }\n\n assessment.assessedBy = newAssessment.assessedBy; // Update IsExist based on the flag\n\n assessment.IsExist = validCrewCount > 0;\n return assessment;\n }\n /**\r\n * Get only the reports that have a stored or complete Assessment\r\n * @memberof CrewAssessmentFactory\r\n * @returns {Array} crewAssesments \r\n */\n\n\n function getAssesedCabinReports() {\n var reports = CabinReportLocalEditFactory.getCabinReportsFromStorage();\n var assessments = getCrewAssessmentsFromStorage();\n var assesedReports = [];\n\n for (var i = 0; i < assessments.length; i++) {\n if (assessments[i].Status != \"Completed\" && !assessments[i].IsExist && assessments[i].CrewAssessmentMembers.length > 0) {\n var isCompleted = true;\n var routeReports = [];\n\n for (var j = 0; j < reports.length; j++) {\n if (reports[j].Route == assessments[i].Route && reports[j].DutyDate == assessments[i].DutyDate) {\n if (reports[j].Status != \"completed\") {\n isCompleted = false;\n } else {\n routeReports.push(reports[j]);\n }\n }\n }\n\n if (isCompleted) {\n var flights = FlightFactory.getFlightsByRoute(assessments[i].Route, assessments[i].DutyDate);\n\n for (var j = 0; j < flights.length; j++) {\n if (flights[j].cabinReportStatusDescr == \"Pending\") {\n isCompleted = false;\n break;\n }\n }\n }\n\n if (!isCompleted) {\n assesedReports = assesedReports.concat(routeReports);\n } else if (routeReports != []) {\n routeReports.sort(function (a, b) {\n return new Date(b.ScheduledDeparture) - new Date(a.ScheduledDeparture);\n });\n routeReports.splice(0, 1);\n assesedReports = assesedReports.concat(routeReports);\n }\n } else {\n for (var j = 0; j < reports.length; j++) {\n if (reports[j].Route == assessments[i].Route && reports[j].DutyDate == assessments[i].DutyDate) {\n if (reports[j].Status == \"completed\") {\n assesedReports.push(reports[j]);\n }\n }\n }\n }\n } //orphaned reports\n\n\n for (var j = 0; j < reports.length; j++) {\n if (!existsForRouteDutyDate(reports[j].Route, reports[j].DutyDate)) {\n if (reports[j].Status == \"completed\") {\n assesedReports.push(reports[j]);\n }\n }\n }\n\n return assesedReports;\n }\n /**\r\n * Find if an assessment exists for the selected Route and Duty Date\r\n * @memberof CrewAssessmentFactory\r\n * @param {string} Route The route of the assessment\r\n * @param {string} DutyDate The duty date of the assessment\r\n * @returns {boolean} isExist \r\n */\n\n\n function existsForRouteDutyDate(Route, DutyDate) {\n var assessments = getCrewAssessmentsFromStorage();\n var isExist = false;\n\n for (var j = 0; j < assessments.length; j++) {\n if (assessments[j].Route == Route && assessments[j].DutyDate == DutyDate) {\n isExist = true;\n break;\n }\n }\n\n return isExist;\n }\n /**\r\n * Update Assessment Information from flights\r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} crewAssessment The crew assessment\r\n * @param {Array} flights The flights of the Assessment\r\n */\n\n\n function updateAssessmentFlights(crewAssessment, flights) {\n for (var i = 0; i < flights.length; i++) {\n if (crewAssessment.start && crewAssessment.end) {\n var flightStart = Date.parse(flights[i].ScheduledDeparture);\n var flightEnd = Date.parse(flights[i].ScheduledArrival);\n var assesmentStart = Date.parse(crewAssessment.start);\n\n if (flightStart < assesmentStart) {\n crewAssessment.start = flights[i].ScheduledDeparture;\n } else {\n var assesmentEnd = Date.parse(crewAssessment.end);\n\n if (flightEnd > assesmentEnd) {\n crewAssessment.end = flights[i].ScheduledArrival;\n }\n }\n } else {\n crewAssessment.start = flights[i].ScheduledDeparture;\n crewAssessment.end = flights[i].ScheduledArrival;\n }\n\n var flight = {\n ScheduledDepartureDateUTC: flights[i].ScheduledDepartureDateUTC,\n FlightNo: flights[i].FlightNo,\n Departure: flights[i].Departure,\n Arrival: flights[i].Arrival,\n ScheduledDepartureTimeUTC: flights[i].ScheduledDepartureTimeUTC,\n ScheduledDeparture: flights[i].ScheduledDeparture,\n ScheduledArrival: flights[i].ScheduledArrival,\n AcTailNo: flights[i].AcTailNo\n };\n crewAssessment.Flights.push(flight);\n }\n\n return crewAssessment;\n }\n /**\r\n * Returns the a list of cabin Crew Feedbacks that are ready to send (the reports of the assessment are completed or synched)\r\n * @memberof CrewAssessmentFactory\r\n * @param {string} Route The route of the assessment\r\n * @param {string} DutyDate The duty date of the assessment\r\n * @returns {Array} assessmentsToSend \r\n */\n\n\n function getAssementsReadyToSend() {\n var assessments = getCrewAssessmentsFromStorage();\n var assessmentsToSend = [];\n\n for (var i = 0; i < assessments.length; i++) {\n if (assessments[i].Status == \"Completed\") {\n assessmentsToSend.push(assessments[i]); ////Send assessments anyway...\n // var isCompleted = true;\n // var flights = FlightFactory.getFlightsByRoute(assessments[i].Route, assessments[i].DutyDate);\n // for (var j = 0; j < flights.length; j++) {\n // \tif (flights[j].LineStatus == \"pending\" || flights[j].LineStatus == \"pendingoverdue\" || flights[j].LineStatus == \"draft\") {\n // \t\tisCompleted = false;\n // \t\tbreak;\n // \t}\n // }\n // if (isCompleted) {\n // \tassessmentsToSend.push(assessments[i])\n // }\n }\n }\n\n return assessmentsToSend;\n }\n /**\r\n * Store Assessment inside the flights\r\n * @memberof CrewAssessmentFactory\r\n */\n\n\n function storeFlightsWithAssessments() {\n var flights = FlightFactory.getFlightsFromStorage();\n var crewAssessments = getCrewAssessmentsFromStorage();\n\n for (var i = 0; i < flights.length; i++) {\n for (var j = 0; j < crewAssessments.length; j++) {\n if (flights[i].Route == crewAssessments[j].Route && flights[i].DutyDate == crewAssessments[j].DutyDate) {\n flights[i].assessment = {\n Id: crewAssessments[j].Id,\n Status: crewAssessments[j].Status,\n IsExist: crewAssessments[j].IsExist,\n IsAssessedBy: crewAssessments[j].assessedBy.length > 0,\n IsCrewLess: crewAssessments[j].CrewAssessmentMembers.length < 1\n };\n break;\n }\n }\n }\n\n FlightFactory.setFlightsToStorage(flights);\n }\n /**\r\n * Update Assessments which are stored inside the flights \r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} crewAssessment The crew assessment\\\r\n */\n\n\n function updateFlightsAssessment(assessment) {\n var flights = FlightFactory.getFlightsFromStorage();\n\n for (var i = 0; i < flights.length; i++) {\n if (flights[i].assessment && flights[i].assessment.Id == assessment.Id) {\n flights[i].assessment.Status = assessment.Status;\n }\n }\n\n FlightFactory.setFlightsToStorage(flights);\n }\n /**\r\n * Store Assessment inside the crewRoutes\r\n * @memberof CrewAssessmentFactory\r\n */\n\n\n function storeCrewRoutesWithAssessments() {\n var crewRoutes = CrewRouteFactory.getCrewRoutesFromStorage();\n var crewAssessments = getCrewAssessmentsFromStorage();\n\n for (var i = 0; i < crewRoutes.length; i++) {\n for (var j = 0; j < crewAssessments.length; j++) {\n if (crewRoutes[i].Route == crewAssessments[j].Route && crewRoutes[i].DutyDay == crewAssessments[j].DutyDay) {\n crewRoutes[i].AssessmentInfo = {\n Id: crewAssessments[j].Id,\n Status: crewAssessments[j].Status,\n IsExist: crewAssessments[j].IsExist // IsAssessedBy: crewAssessments[j].assessedBy.length > 0,\n // IsCrewLess: crewAssessments[j].CrewAssessmentMembers.length < 1,\n\n };\n break;\n }\n }\n }\n\n CrewRouteFactory.setCrewRoutesToStorage(crewRoutes);\n }\n /**\r\n * Update Assessments which are stored inside the crewRoute \r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} crewAssessment The crew assessment\\\r\n */\n\n\n function updateCrewRouteAssessment(assessment) {\n var crewRoutes = CrewRouteFactory.getCrewRoutesFromStorage();\n\n for (var i = 0; i < crewRoutes.length; i++) {\n if (crewRoutes[i].AssessmentInfo && crewRoutes[i].AssessmentInfo.Id == assessment.Id) {\n crewRoutes[i].AssessmentInfo.Status = assessment.Status;\n }\n }\n\n CrewRouteFactory.setCrewRoutesToStorage(crewRoutes);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CrewAssessmentCreatorFactory', CrewAssessmentCreatorFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewAssessmentCreatorFactory\r\n * @description \r\n * Initializes new Crew Assessments\r\n * @ngInject\r\n */\n\n function CrewAssessmentCreatorFactory(UserFactory, CrewAssessmentFactory, CrewAssessmentTemplateFactory, FlightFactory, CrewAssessmentMemberFactory) {\n var service = {\n createNewCrewAssessment: createNewCrewAssessment,\n createCrewAssessments: createCrewAssessments\n };\n /**\r\n * Create New Crew Assessment from the api assessments\r\n * @memberof CrewAssessmentCreatorFactory\r\n * @returns {object} assessment \r\n */\n\n function createNewCrewAssessment(assessment) {\n // load the user\n var user = UserFactory.getUser();\n if (user == null) return null; // load the crewAssessmentTemplate\n\n var crewAssessmentTemplates = CrewAssessmentTemplateFactory.getCrewAssessmentTemplateFromStorage();\n if (crewAssessmentTemplates == null) return null; // load the flight\n\n var flights = FlightFactory.getFlightsByRoute(assessment.Route, assessment.DutyDate);\n if (flights == null || flights.length == 0) return null; // create the new crewAssessment\n\n var crewAssessment = CrewAssessmentFactory.getNewCrewAssessment();\n crewAssessment.Id = assessment.Id == null ? guid() : assessment.Id;\n crewAssessment.UserId = user.id;\n crewAssessment.Route = assessment.Route;\n crewAssessment.DutyDate = assessment.DutyDate;\n crewAssessment.DutyDay = assessment.DutyDay;\n crewAssessment.AcType = flights[0].AcType;\n crewAssessment = CrewAssessmentFactory.updateAssessmentFlights(crewAssessment, flights);\n crewAssessment.assessedBy = assessment.assessedBy;\n var IsExist = true;\n\n for (var i = 0; i < assessment.assessmentCrew.length; i++) {\n var crewMember = CrewAssessmentMemberFactory.newMember();\n crewMember.aimsId = assessment.assessmentCrew[i].CrewAimsId;\n crewMember.id = assessment.assessmentCrew[i].CrewId;\n crewMember.assessmentItems = crewAssessmentTemplates;\n crewMember.name = assessment.assessmentCrew[i].Name;\n crewMember.IsCompleted = false;\n crewMember.IsValid = true;\n crewMember.IsExist = assessment.assessmentCrew[i].IsExist;\n crewMember.IsOutdated = assessment.assessmentCrew[i].IsOutdated;\n crewMember.EndPeriod = assessment.assessmentCrew[i].EndPeriod;\n\n if (!assessment.assessmentCrew[i].IsExist) {\n IsExist = false;\n }\n\n crewAssessment.CrewAssessmentMembers.push(crewMember);\n }\n\n crewAssessment.IsExist = IsExist;\n\n if (IsExist) {\n crewAssessment.Status = \"Stored\";\n } // return the new crewAssessment\n\n\n return crewAssessment;\n }\n /**\r\n * Create New Crew Assessments from the api assessments\r\n * @memberof CrewAssessmentCreatorFactory\r\n * @returns {Array} crewAssessments \r\n */\n\n\n function createCrewAssessments(assessments) {\n var crewAssessments = [];\n\n for (var i = 0; i < assessments.length; i++) {\n var crewAssessment = createNewCrewAssessment(assessments[i]);\n\n if (crewAssessment) {\n crewAssessments.push(crewAssessment);\n }\n }\n\n return crewAssessments;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CrewAssessmentMemberFactory', CrewAssessmentMemberFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewAssessmentMemberFactory\r\n * @description \r\n * Initializes new Crew Assessment Members\r\n * @ngInject\r\n */\n\n function CrewAssessmentMemberFactory() {\n /**\r\n * Initialize the Crew Assessment Member\r\n * @memberof CrewAssessmentMemberFactory\r\n */\n function CrewAssessmentMember() {\n this.aimsId = null;\n this.id = null;\n this.name = null;\n this.IsCompleted = false;\n this.IsValid = true;\n this.IsOverride = false;\n this.IsManual = false;\n this.IsExist = false;\n this.Review = null;\n this.assessmentItems = [];\n this.IsOutdated = false;\n this.EndPeriod = null;\n }\n\n var service = {\n newMember: newMember\n };\n /**\r\n * Create New Crew Assessment Member\r\n * @memberof CrewAssessmentMemberFactory\r\n * @returns {object} CrewAssessmentMember \r\n */\n\n function newMember() {\n return new CrewAssessmentMember();\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CrewAssessmentTemplateFactory', CrewAssessmentTemplateFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewAssessmentTemplateFactory\r\n * @description \r\n * Get,Set new Crew Assessment Templates\r\n * @ngInject\r\n */\n\n function CrewAssessmentTemplateFactory(GenericService) {\n /**\r\n * Initialize the Crew Assessment Template\r\n * @memberof CrewAssessmentTemplateFactory\r\n */\n function CrewAssessmentTemplate() {\n this.Id = null;\n this.Description = null;\n this.Label = null;\n this.OrderNo = null;\n this.ItemValue = 3;\n this.GetId = GetId;\n }\n\n var objType = 'CrewAssessmentTemplate';\n var objCallback = CrewAssessmentTemplate;\n var service = {\n getCrewAssessmentTemplateFromStorage: getCrewAssessmentTemplateFromStorage,\n setCrewAssessmentTemplateToStorage: setCrewAssessmentTemplateToStorage\n }; //Object services\n\n /**\r\n * Overide default get Id\r\n * @memberof CrewAssessmentTemplateFactory\r\n * @returns {number} Id \r\n */\n\n function GetId() {\n return this.Id;\n } // Factory Services\n\n /**\r\n * Get Crew Assessment Templates\r\n * @memberof CrewAssessmentTemplateFactory\r\n * @returns {Array} CrewAssessmentTemplates \r\n */\n\n\n function getCrewAssessmentTemplateFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Get Assessment Sync Results\r\n * @memberof CrewAssessmentTemplateFactory\r\n * @param {Array} CrewAssessmentTemplates A list of Crew assesment template questions\r\n */\n\n\n function setCrewAssessmentTemplateToStorage(crewAssessmentTemplate) {\n GenericService.saveAll(crewAssessmentTemplate, objType, objCallback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('AssignmentModalCtrl', AssignmentModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name AssignmentModalCtrl\r\n * @description \r\n * Manages the Assignment Modal\r\n * @ngInject\r\n */\n\n function AssignmentModalCtrl($scope, assignment, info, $uibModalInstance, CampaignFactory) {\n $scope.assignment = JSON.parse(JSON.stringify(assignment));\n $scope.info = info;\n $scope.cancel = cancel;\n $scope.submit = submit;\n $scope.giftStatus = CampaignFactory.giftStatusList();\n /**\r\n * Close the modal\r\n * @memberof AssignmentModalCtrl\r\n */\n\n function cancel() {\n $uibModalInstance.dismiss('close');\n }\n\n function submit() {\n CampaignFactory.updateCampaignPassenger(info.flightId, $scope.assignment);\n $uibModalInstance.close('close');\n }\n }\n})();\n\"use strict\";\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CampaignFactory', CampaignFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CampaignFactory\r\n * @description \r\n * Add, Update, Delete and Get Campaigns.\r\n * @ngInject\r\n */\n\n function CampaignFactory(GenericService, FlightFactory) {\n var objType = 'Campaigns';\n var objCallback = Campaign;\n /**\r\n * Initialize the Campaign\r\n * @memberof CampaignFactory\r\n */\n\n function Campaign() {\n this.GetId = GetId;\n }\n\n var service = {\n giftStatusList: giftStatusList,\n getFlightsCampaignsFromStorage: getFlightsCampaignsFromStorage,\n getCampaignsByFlightId: getCampaignsByFlightId,\n saveFlightCampaignsToStorage: saveFlightCampaignsToStorage,\n updateCampaignPassenger: updateCampaignPassenger,\n updateSeatNoPaxAssignments: updateSeatNoPaxAssignments,\n getPaxAssignmentsFromStorage: getPaxAssignmentsFromStorage,\n mergeCampaigns: mergeCampaigns,\n getPaxAssignment: getPaxAssignment,\n hasPendingFeedbacks: hasPendingFeedbacks,\n syncResultFormat: syncResultFormat,\n cleanOldCampaigns: cleanOldCampaigns\n }; //Object Functions\n\n /**\r\n * Overide default get Id\r\n * @memberof FlightFactory\r\n * @returns {number} Id \r\n */\n\n function GetId() {\n return this.FlightId;\n }\n /**\r\n * Get Campaigns\r\n * @memberof CampaignFactory\r\n * @param {function} callback \r\n */\n\n\n function getFlightsCampaignsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n\n ;\n /**\r\n * Save Campaigns to storage\r\n * @memberof CampaignFactory\r\n * @param {Array} flightCampaigns A list of flightCampaigns\r\n */\n\n function setFlightCampaignsToStorage(flightCampaigns) {\n GenericService.saveAll(flightCampaigns, objType, objCallback);\n }\n /**\r\n * Get single flight Campaigns\r\n * @memberof CampaignFactory\r\n * @param {function} callback \r\n */\n\n\n function getCampaignsByFlightId(flightId) {\n return GenericService.get(flightId, objType, objCallback);\n }\n\n ;\n /**\r\n * Set single flight Campaigns\r\n * @memberof CampaignFactory\r\n * @param {function} callback \r\n */\n\n function addFlightCampaigns(FlightCampaigns) {\n FlightCampaigns.IsFeedbackReady = !hasPendingFeedbacks(FlightCampaigns);\n return GenericService.add(FlightCampaigns, objType, objCallback);\n }\n\n ;\n /**\r\n * Get assignments from storage\r\n * @memberof CampaignFactory\r\n * @param {function} callback \r\n */\n\n function getPaxAssignmentsFromStorage() {\n var assignmentsToSend = [];\n var data = getFlightsCampaignsFromStorage();\n\n if (data) {\n var flightsReadyList = data.filter(function (d) {\n return d.IsFeedbackReady;\n });\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = flightsReadyList[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var flight = _step.value;\n var flightStored = FlightFactory.getFlightFromStorage(flight.FlightId);\n var isSyncTimeValid = flightStored == null || moment().valueOf() > moment.utc(flightStored.ScheduledDeparture).valueOf();\n\n if (isSyncTimeValid) {\n flight.CampaignsList.forEach(function (camp) {\n camp.Treatments.forEach(function (treat) {\n treat.Assignments.forEach(function (assign) {\n var assignToSend = _objectSpread({}, assign, {\n Status: +assign.StatusStr\n });\n\n assignmentsToSend.push(assignToSend);\n });\n });\n });\n } // else{\n // clearFlightCampaignsFromStorage(flight.FlightId)\n // }\n\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator[\"return\"] != null) {\n _iterator[\"return\"]();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return {\n FlightsToFetch: data.map(function (flt) {\n return flt.FlightId;\n }),\n AssignmentsToUpdate: assignmentsToSend\n };\n }\n }\n\n ;\n /**\r\n * Get assignment from storage with flightId, PNR, UCI\r\n * @memberof CampaignFactory\r\n * @param {function} callback \r\n */\n\n function getPaxAssignment(flightId, pnr, uci) {\n var fltCampaigns = getCampaignsByFlightId(flightId);\n var data = {\n campaign: null,\n treatment: null,\n assignment: null\n };\n\n if (fltCampaigns) {\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = fltCampaigns.CampaignsList[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var camp = _step2.value;\n data.campaign = {\n title: camp.CampaignTitle,\n briefings: camp.Briefings\n };\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = camp.Treatments[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var treat = _step3.value;\n data.treatment = {\n title: treat.Title,\n description: treat.Description,\n briefings: treat.Briefings\n };\n data.assignment = treat.Assignments.find(function (a) {\n return a.UCI == uci && a.PNR == pnr;\n });\n if (data.assignment) break;\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3[\"return\"] != null) {\n _iterator3[\"return\"]();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n\n if (data.assignment) break;\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2[\"return\"] != null) {\n _iterator2[\"return\"]();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n }\n\n return data;\n }\n\n function mergeCampaigns(data) {\n //Current flights to store\n var flightIdList = getFlightsCampaignsFromStorage().map(function (x) {\n return x.FlightId;\n });\n\n if (data.UpdateAssignmentsSuccess) {\n var incomingfltIds = data.FlightsCampaigns.map(function (x) {\n return x.FlightId;\n });\n flightIdList.forEach(function (id) {\n if (!incomingfltIds.includes(id)) {\n clearFlightCampaignsFromStorage(id);\n }\n });\n }\n\n if (data.GetAssignmentsSuccess) {\n updateIncomingStore(data.FlightsCampaigns);\n data.FlightsCampaigns.forEach(function (flight) {\n //curent store not include incoming flight\n if (!flightIdList.includes(flight.FlightId)) addFlightCampaigns(flight); //current store include flight\t\n else saveFlightCampaignsToStorage(flight);\n });\n }\n }\n\n function updateIncomingStore(incomingCamps) {\n var _iteratorNormalCompletion4 = true;\n var _didIteratorError4 = false;\n var _iteratorError4 = undefined;\n\n try {\n for (var _iterator4 = incomingCamps[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {\n var flt = _step4.value;\n var _iteratorNormalCompletion5 = true;\n var _didIteratorError5 = false;\n var _iteratorError5 = undefined;\n\n try {\n for (var _iterator5 = flt.CampaignsList[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {\n var camp = _step5.value;\n var _iteratorNormalCompletion6 = true;\n var _didIteratorError6 = false;\n var _iteratorError6 = undefined;\n\n try {\n for (var _iterator6 = camp.Treatments[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {\n var treat = _step6.value;\n var _iteratorNormalCompletion7 = true;\n var _didIteratorError7 = false;\n var _iteratorError7 = undefined;\n\n try {\n for (var _iterator7 = treat.Assignments[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {\n var assign = _step7.value;\n var currentAssignment = findCurrentAssignment(assign);\n\n if (currentAssignment) {\n //&& ((assign.AutoSet && !currentAssignment.AutoSet) || (!assign.AutoSet && !currentAssignment.AutoSet))) {\n assign.Status = currentAssignment.Status;\n assign.StatusStr = currentAssignment.StatusStr;\n assign.Rate = currentAssignment.Rate;\n assign.Comments = currentAssignment.Comments; //assign.AutoSet = currentAssignment.Status != 5 ? false : currentAssignment.AutoSet;\n }\n }\n } catch (err) {\n _didIteratorError7 = true;\n _iteratorError7 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion7 && _iterator7[\"return\"] != null) {\n _iterator7[\"return\"]();\n }\n } finally {\n if (_didIteratorError7) {\n throw _iteratorError7;\n }\n }\n }\n }\n } catch (err) {\n _didIteratorError6 = true;\n _iteratorError6 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion6 && _iterator6[\"return\"] != null) {\n _iterator6[\"return\"]();\n }\n } finally {\n if (_didIteratorError6) {\n throw _iteratorError6;\n }\n }\n }\n }\n } catch (err) {\n _didIteratorError5 = true;\n _iteratorError5 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion5 && _iterator5[\"return\"] != null) {\n _iterator5[\"return\"]();\n }\n } finally {\n if (_didIteratorError5) {\n throw _iteratorError5;\n }\n }\n }\n }\n } catch (err) {\n _didIteratorError4 = true;\n _iteratorError4 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion4 && _iterator4[\"return\"] != null) {\n _iterator4[\"return\"]();\n }\n } finally {\n if (_didIteratorError4) {\n throw _iteratorError4;\n }\n }\n }\n }\n\n function findCurrentAssignment(assignment) {\n var currentCamps = getFlightsCampaignsFromStorage();\n var currentAssignment;\n var _iteratorNormalCompletion8 = true;\n var _didIteratorError8 = false;\n var _iteratorError8 = undefined;\n\n try {\n for (var _iterator8 = currentCamps[Symbol.iterator](), _step8; !(_iteratorNormalCompletion8 = (_step8 = _iterator8.next()).done); _iteratorNormalCompletion8 = true) {\n var flt = _step8.value;\n var _iteratorNormalCompletion9 = true;\n var _didIteratorError9 = false;\n var _iteratorError9 = undefined;\n\n try {\n for (var _iterator9 = flt.CampaignsList[Symbol.iterator](), _step9; !(_iteratorNormalCompletion9 = (_step9 = _iterator9.next()).done); _iteratorNormalCompletion9 = true) {\n var camp = _step9.value;\n var _iteratorNormalCompletion10 = true;\n var _didIteratorError10 = false;\n var _iteratorError10 = undefined;\n\n try {\n for (var _iterator10 = camp.Treatments[Symbol.iterator](), _step10; !(_iteratorNormalCompletion10 = (_step10 = _iterator10.next()).done); _iteratorNormalCompletion10 = true) {\n var treat = _step10.value;\n currentAssignment = treat.Assignments.find(function (assign) {\n return assign.Id == assignment.Id;\n });\n if (currentAssignment) break;\n }\n } catch (err) {\n _didIteratorError10 = true;\n _iteratorError10 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion10 && _iterator10[\"return\"] != null) {\n _iterator10[\"return\"]();\n }\n } finally {\n if (_didIteratorError10) {\n throw _iteratorError10;\n }\n }\n }\n\n if (currentAssignment) break;\n }\n } catch (err) {\n _didIteratorError9 = true;\n _iteratorError9 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion9 && _iterator9[\"return\"] != null) {\n _iterator9[\"return\"]();\n }\n } finally {\n if (_didIteratorError9) {\n throw _iteratorError9;\n }\n }\n }\n\n if (currentAssignment) break;\n }\n } catch (err) {\n _didIteratorError8 = true;\n _iteratorError8 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion8 && _iterator8[\"return\"] != null) {\n _iterator8[\"return\"]();\n }\n } finally {\n if (_didIteratorError8) {\n throw _iteratorError8;\n }\n }\n }\n\n return currentAssignment;\n }\n /**\r\n * Update FlightCampaigns to Storage\r\n * @memberof CampaignFactory\r\n * @param {object} CampaignPassenger a CampaignPassenger\r\n */\n\n\n function saveFlightCampaignsToStorage(campaignPassenger) {\n campaignPassenger.IsFeedbackReady = !hasPendingFeedbacks(campaignPassenger);\n GenericService.save(campaignPassenger, objType, objCallback);\n }\n\n ;\n\n function updateCampaignPassenger(flightId, assignment) {\n var data = getCampaignsByFlightId(flightId);\n var assignmentLs;\n\n if (data) {\n var fltCampaings = _objectSpread({}, data);\n\n var _iteratorNormalCompletion11 = true;\n var _didIteratorError11 = false;\n var _iteratorError11 = undefined;\n\n try {\n for (var _iterator11 = fltCampaings.CampaignsList[Symbol.iterator](), _step11; !(_iteratorNormalCompletion11 = (_step11 = _iterator11.next()).done); _iteratorNormalCompletion11 = true) {\n var camp = _step11.value;\n var _iteratorNormalCompletion12 = true;\n var _didIteratorError12 = false;\n var _iteratorError12 = undefined;\n\n try {\n for (var _iterator12 = camp.Treatments[Symbol.iterator](), _step12; !(_iteratorNormalCompletion12 = (_step12 = _iterator12.next()).done); _iteratorNormalCompletion12 = true) {\n var treat = _step12.value;\n assignmentLs = treat.Assignments.find(function (a) {\n return a.Id == assignment.Id;\n });\n\n if (assignmentLs) {\n assignmentLs.Status = +assignment.StatusStr;\n assignmentLs.StatusStr = assignment.StatusStr;\n assignmentLs.Rate = +assignment.StatusStr == 1 ? assignment.Rate : 0;\n assignmentLs.Comments = assignment.Comments; //delete assignmentLs[\"AutoSet\"];\n\n break;\n }\n }\n } catch (err) {\n _didIteratorError12 = true;\n _iteratorError12 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion12 && _iterator12[\"return\"] != null) {\n _iterator12[\"return\"]();\n }\n } finally {\n if (_didIteratorError12) {\n throw _iteratorError12;\n }\n }\n }\n\n if (assignmentLs) break;\n }\n } catch (err) {\n _didIteratorError11 = true;\n _iteratorError11 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion11 && _iterator11[\"return\"] != null) {\n _iterator11[\"return\"]();\n }\n } finally {\n if (_didIteratorError11) {\n throw _iteratorError11;\n }\n }\n }\n\n saveFlightCampaignsToStorage(fltCampaings);\n }\n }\n\n function updateSeatNoPaxAssignments(fltCampaings, paxinfoList) {\n fltCampaings.forEach(function (fltcamp) {\n fltcamp.CampaignsList.forEach(function (camp) {\n var paxinfo = paxinfoList.find(function (p) {\n return p.FlightId == fltcamp.FlightId;\n });\n\n if (paxinfo) {\n var paxinfoFlatten = flatten(paxinfo.Seatmap.map(function (s) {\n return s.Columns;\n }));\n camp.Treatments.forEach(function (treat) {\n treat.Assignments.forEach(function (assign) {\n var pax = paxinfoFlatten.find(function (s) {\n return s.PNR == assign.PNR && s.UCI == assign.UCI;\n });\n\n if (pax) {\n assign.SeatNo = pax.SeatNo;\n } // else {\n // \tassign.Status = 5;\n // \tassign.AutoSet = true;\n // \tassign.StatusStr = '5';\n // \tassign.Comments = null;\n // \tassign.Rate = 0;\n // }\n\n });\n });\n }\n });\n });\n }\n\n function giftStatusList() {\n return [{\n label: \"-select one-\",\n value: \"0\"\n }, {\n label: \"Delivered\",\n value: \"1\"\n }, {\n label: \"Not delivered\",\n value: \"2\"\n }, {\n label: \"Damaged\",\n value: \"3\"\n }, {\n label: \"Not available\",\n value: \"4\"\n }, {\n label: \"No show\",\n value: \"5\"\n }, {\n label: \"No interest\",\n value: \"7\"\n }];\n }\n /**\r\n * Remove fligthcampaigns from the local storage\r\n * @memberof CampaignFactory\r\n */\n\n\n function clearFlightCampaignsFromStorage(flightId) {\n GenericService.remove(flightId, objType, objCallback);\n }\n\n function hasPendingFeedbacks(data) {\n var feedbackReadyCounter = 0; //var data = getCampaignsByFlightId(flightId);\n\n if (data) {\n var _iteratorNormalCompletion13 = true;\n var _didIteratorError13 = false;\n var _iteratorError13 = undefined;\n\n try {\n for (var _iterator13 = data.CampaignsList[Symbol.iterator](), _step13; !(_iteratorNormalCompletion13 = (_step13 = _iterator13.next()).done); _iteratorNormalCompletion13 = true) {\n var camp = _step13.value;\n var _iteratorNormalCompletion14 = true;\n var _didIteratorError14 = false;\n var _iteratorError14 = undefined;\n\n try {\n for (var _iterator14 = camp.Treatments[Symbol.iterator](), _step14; !(_iteratorNormalCompletion14 = (_step14 = _iterator14.next()).done); _iteratorNormalCompletion14 = true) {\n var treat = _step14.value;\n feedbackReadyCounter += treat.Assignments.filter(function (a) {\n return a.Status > 0;\n }).length;\n }\n } catch (err) {\n _didIteratorError14 = true;\n _iteratorError14 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion14 && _iterator14[\"return\"] != null) {\n _iterator14[\"return\"]();\n }\n } finally {\n if (_didIteratorError14) {\n throw _iteratorError14;\n }\n }\n }\n }\n } catch (err) {\n _didIteratorError13 = true;\n _iteratorError13 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion13 && _iterator13[\"return\"] != null) {\n _iterator13[\"return\"]();\n }\n } finally {\n if (_didIteratorError13) {\n throw _iteratorError13;\n }\n }\n }\n }\n\n return !(data.AssignmentsCounter == feedbackReadyCounter);\n }\n\n function syncResultFormat(result) {\n var updateText;\n var upClass;\n var fetchText;\n var fetchClass;\n\n if (result.UpdateAssignmentsSuccess == null) {\n updateText = \"No Campaigns Feedbacks were uploaded to the server. \";\n upClass = \"alert-cyan\";\n } else if (result.UpdateAssignmentsSuccess == true) {\n updateText = \"Campaigns Feedbacks were uploaded to the server. \";\n upClass = \"alert-cyan\";\n } else {\n updateText = \"Campaigns Feedbacks failed to be uploaded to the server. \";\n upClass = \"alert-deep-orange\";\n }\n\n if (result.GetAssignmentsSuccess == false) {\n fetchText = \"Campaigns Feedbacks failed to be fetched by the server.\";\n fetchClass = \"alert-deep-orange\";\n } else if (result.GetAssignmentsSuccess == true && result.FlightsCampaigns.length > 0) {\n fetchText = \"Campaigns Feedbacks were fetched by the server.\";\n fetchClass = \"alert-cyan\";\n } else {\n fetchText = \"No Campaigns Feedbacks were fetched by the server.\";\n fetchClass = \"alert-cyan\";\n }\n\n return {\n updMessage: updateText,\n updClass: upClass,\n ftcMessage: fetchText,\n ftcClass: fetchClass\n };\n }\n\n function flatten(arr) {\n return arr.reduce(function (flat, toFlatten) {\n return flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);\n }, []);\n }\n /**\r\n * Clean Old Data\r\n * @memberof CampaignFactory\r\n * @param {Array} pendingFlightIds FlightIds with pending reports\r\n */\n\n\n function cleanOldCampaigns(pendingFlightIds) {\n var now = moment();\n getFlightsCampaignsFromStorage(function (campaigns) {\n var pendingCampaigns = campaigns.FlightsCampaigns.filter(function (item) {\n return pendingFlightIds.includes(item.FlightId);\n }); // keep only the campaigns with pending reports\n\n setFlightCampaignsToStorage(pendingCampaigns);\n });\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.filter('bytes', bytes);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc filter\r\n * @name bytes\r\n * @description \r\n * Transform Bytes to 'kB', 'MB', 'GB', 'TB', 'PB'\r\n * @ngInject\r\n */\n\n function bytes() {\n return function (bytes, precision) {\n if (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';\n if (typeof precision === 'undefined') precision = 1;\n var units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],\n number = Math.floor(Math.log(bytes) / Math.log(1024));\n return (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number];\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('DataCleanerFactory', DataCleanerFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name DataCleanerFactory\r\n * @description \r\n * Cleans the Data of the application\r\n * @ngInject\r\n */\n\n function DataCleanerFactory(localStorageMD5Service, IndexedDBService, GenericService) {\n var service = {\n deleteAllReports: deleteAllReports,\n deleteAllServerData: deleteAllServerData,\n deleteAllData: deleteAllData,\n deleteOrphanedLocalFlights: deleteOrphanedLocalFlights,\n deleteOrphanedLocalReports: deleteOrphanedLocalReports,\n deleteSynchedLocalCabinReports: deleteSynchedLocalCabinReports,\n deleteIndexedDB: deleteIndexedDB,\n deleteOldCrewMealsRatings: deleteOldCrewMealsRatings,\n deleteOrphanedCustomerEvents: deleteOrphanedCustomerEvents\n };\n /**\r\n * Delete All Cabin Reports\r\n * @memberof DataCleanerFactory\r\n */\n\n function deleteAllReports() {\n localStorageMD5Service.remove('cabinReportLocalEdits');\n localStorageMD5Service.remove('cabinReportLocalEdit_TEMP');\n deleteOrphanedLocalFlights();\n }\n\n ;\n /**\r\n * Delete Basic Server data\r\n * @memberof DataCleanerFactory\r\n */\n\n function deleteAllServerData() {\n localStorageMD5Service.remove('flights');\n localStorageMD5Service.remove('reportGuids');\n localStorageMD5Service.remove('aircraftTypes');\n localStorageMD5Service.remove('cabinReportTemplateItems');\n localStorageMD5Service.remove('cabinReportSyncResults');\n localStorageMD5Service.remove('assessmentSyncResults');\n localStorageMD5Service.remove('waterUpliftActions');\n localStorageMD5Service.remove('acSupplies');\n localStorageMD5Service.remove('specialMealSources');\n localStorageMD5Service.remove('specialMealTypes');\n localStorageMD5Service.remove('currencies');\n localStorageMD5Service.remove('travelValueIncompleteReasons');\n localStorageMD5Service.remove('incompleteInFlightServiceListOfValues');\n localStorageMD5Service.remove('ccms');\n localStorageMD5Service.remove('scheduleChanges');\n localStorageMD5Service.remove('CheckIn');\n localStorageMD5Service.remove('flightCheckIns');\n localStorageMD5Service.remove('CrewAssessmentTemplate');\n localStorageMD5Service.remove('FAQItem');\n localStorageMD5Service.remove('PaxInfo');\n localStorageMD5Service.remove('flightEventTypes');\n localStorageMD5Service.remove('flightEvents');\n deleteOrphanedLocalFlights();\n }\n\n ;\n /**\r\n * Delete All Server data\r\n * @memberof DataCleanerFactory\r\n */\n\n function deleteAllData() {\n localStorageMD5Service.clearAll();\n IndexedDBService.deleteDatabase();\n }\n\n ;\n\n function deleteIndexedDB() {\n return IndexedDBService.deleteDatabase();\n }\n /**\r\n * Delete local flights that have no stored local reports\r\n * @memberof DataCleanerFactory\r\n */\n\n\n function deleteOrphanedLocalFlights() {\n var existingLocalFlights = localStorageMD5Service.get('localFlights');\n if (existingLocalFlights == null) return;\n var finalLocalFlights = [];\n var cabinReportLocalEdits = localStorageMD5Service.get('cabinReportLocalEdits');\n if (cabinReportLocalEdits == null) cabinReportLocalEdits = []; // check every local flight that has a saved cabin report\n\n for (var i = 0; i < existingLocalFlights.length; i++) {\n var hasCabinReport = false;\n\n for (var j = 0; j < cabinReportLocalEdits.length; j++) {\n if (cabinReportLocalEdits[j].FlightId != null && cabinReportLocalEdits[j].FlightId == existingLocalFlights[i].FlightId || cabinReportLocalEdits[j].FlightAimsId != null && cabinReportLocalEdits[j].FlightAimsId == existingLocalFlights[i].FlightAimsId) {\n hasCabinReport = true;\n break;\n }\n } // if it has a cabin report, add it to the flights to save\n\n\n if (hasCabinReport) finalLocalFlights.push(existingLocalFlights[i]);\n } // save the resulting local flights\n\n\n localStorageMD5Service.set('localFlights', finalLocalFlights);\n }\n /**\r\n * Delete local reports that have no stored local flights\r\n * @memberof DataCleanerFactory\r\n */\n\n\n function deleteOrphanedLocalReports() {\n var existingLocalCabinReports = localStorageMD5Service.get('cabinReportLocalEdits');\n var flights = localStorageMD5Service.get('flights');\n if (existingLocalCabinReports == null || flights == null || existingLocalCabinReports.length == 0 || flights.length == 0) return 0;\n var finalLocalCabinReports = [];\n\n for (var i = 0; i < existingLocalCabinReports.length; i++) {\n var remove = false;\n\n if (existingLocalCabinReports[i].Status == 'synched') {\n remove = true;\n\n if (existingLocalCabinReports[i].FlightId != null || existingLocalCabinReports[i].FlightAimsId != null) {\n for (var j = 0; j < flights.length; j++) {\n if (existingLocalCabinReports[i].FlightId != null && existingLocalCabinReports[i].FlightId == flights[j].FlightId || existingLocalCabinReports[i].FlightAimsId != null && existingLocalCabinReports[i].FlightAimsId == flights[j].FlightAimsId) {\n remove = false;\n }\n }\n }\n }\n\n if (!remove) finalLocalCabinReports.push(existingLocalCabinReports[i]);\n } // save the resulting local reports\n\n\n localStorageMD5Service.set('cabinReportLocalEdits', finalLocalCabinReports);\n }\n /**\r\n * Delete Synched Local CabinReports\r\n * @memberof DataCleanerFactory\r\n */\n\n\n function deleteSynchedLocalCabinReports() {\n var existingLocalCabinReports = localStorageMD5Service.get('cabinReportLocalEdits');\n var flights = localStorageMD5Service.get('flights');\n if (existingLocalCabinReports == null || flights == null || existingLocalCabinReports.length == 0 || flights.length == 0) return 0;\n var finalLocalCabinReports = [];\n var deleted = 0;\n var user = localStorageMD5Service.get('user');\n ; // check every saved cabin report\n\n for (var i = 0; i < existingLocalCabinReports.length; i++) {\n var remove = false;\n\n if (existingLocalCabinReports[i].Status == 'synched') {\n if (existingLocalCabinReports[i].FlightId != null || existingLocalCabinReports[i].FlightAimsId != null) {\n for (var j = 0; j < flights.length; j++) {\n if (existingLocalCabinReports[i].FlightId != null && existingLocalCabinReports[i].FlightId == flights[j].FlightId || existingLocalCabinReports[i].FlightAimsId != null && existingLocalCabinReports[i].FlightAimsId == flights[j].FlightAimsId) {\n for (var h = 0; h < flights[j].cabinReports.length; h++) {\n if (flights[j].cabinReports[h].AuthorAimsId == user.aimsId) {\n remove = true;\n deleted++;\n }\n }\n }\n }\n }\n }\n\n if (!remove) finalLocalCabinReports.push(existingLocalCabinReports[i]);\n } // save the resulting local reports\n\n\n localStorageMD5Service.set('cabinReportLocalEdits', finalLocalCabinReports);\n return deleted;\n }\n /**\r\n * Deletes CrewMealRatings that are older than 20 days\r\n * @memberof DataCleanerFactory\r\n */\n\n\n function deleteOldCrewMealsRatings() {\n var res = GenericService.list(\"CrewMealRatings\", objCallbackRatings);\n var lastDate = new Date();\n lastDate.setDate(lastDate.getDate() - 20);\n var crewMealIdsFiltered = res.filter(function (r) {\n return new Date(r.TimeStamp) >= lastDate;\n });\n GenericService.saveOne(crewMealIdsFiltered, \"CrewMealRatings\");\n }\n /**\r\n * Deletes customer events whose flight doesn't exist\r\n */\n\n\n function deleteOrphanedCustomerEvents() {\n var flights = localStorageMD5Service.get('flights');\n var customerEvents = localStorageMD5Service.get('CustomerEvents');\n var finalCustomerEvents = [];\n\n if (customerEvents && flights && flights.length > 0) {\n customerEvents.forEach(function (event) {\n //Search if event's flight exist\n if (flights.find(function (x) {\n return x.FlightId == event.FlightId;\n })) {\n finalCustomerEvents.push(event);\n }\n }); //save the resulting customer events\n\n localStorageMD5Service.set('CustomerEvents', finalCustomerEvents);\n }\n }\n\n function objCallbackRatings() {\n this.CrewMealId = null, this.TimeStamp = null;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.filter('fltSplit', fltSplit);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc filter\r\n * @name messageFilter\r\n * @description \r\n * Filters messages in order to show only the unread.\r\n * @ngInject\r\n */\n\n function fltSplit() {\n return function (fltSplit) {\n var formattedFltNo = fltSplit;\n\n if (typeof fltSplit === 'string' || fltSplit instanceof String) {\n formattedFltNo = fltSplit.replace(/(\\w{2})/, '$1 ');\n }\n\n return formattedFltNo;\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('GenericModalFactory', GenericModalFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name GenericModalFactory\r\n * @description \r\n * Initialize generic Modals\r\n * @ngInject\r\n */\n\n function GenericModalFactory() {\n var service = {\n createNew: createNew,\n fromObject: fromObject,\n deleteFromList: deleteFromList,\n fromObjectList: fromObjectList\n };\n /**\r\n * Greate new Object based on given constructor\r\n * @memberof GenericModalFactory\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} result\r\n */\n\n function createNew(callback) {\n var result = new callback();\n result.Id = guid();\n return result;\n }\n /**\r\n * Extend given object \r\n * @memberof GenericModalFactory\r\n * @param {object} obj The object that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} object\r\n */\n\n\n function fromObject(obj, callback) {\n if (obj == null) return null;\n var object = new callback();\n angular.extend(object, obj);\n return object;\n }\n /**\r\n * Delete an object from given List\r\n * @memberof GenericModalFactory\r\n * @param {object} obj The object that will be removed\r\n * @param {array} objList A list that will be modified\r\n * @returns {array} objList\r\n */\n\n\n function deleteFromList(obj, objList) {\n // find the current item in the array (if present)\n var arrayLength = objList.length;\n var itemIndex = -1;\n\n for (var i = 0; i < arrayLength; i++) {\n if (objList[i].Id == obj.Id) {\n itemIndex = i;\n break;\n }\n }\n\n if (itemIndex >= 0) objList.splice(itemIndex, 1);\n return objList;\n }\n /**\r\n * Extend given object list\r\n * @memberof GenericModalFactory\r\n * @param {array} objList The list of objects that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} objList\r\n */\n\n\n function fromObjectList(objList, callback) {\n if (objList == null) return [];\n var arrayLength = objList.length;\n var newobjList = new Array();\n\n for (var i = 0; i < arrayLength; i++) {\n var obj = new callback();\n angular.extend(obj, objList[i]);\n newobjList.push(obj);\n }\n\n return newobjList;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('GenericService', GenericService);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name GenericService\r\n * @description \r\n * Generic add, edit or remove\r\n * @ngInject\r\n */\n\n function GenericService(localStorageMD5Service) {\n var objectType = null;\n var objectCallback = null;\n var service = {\n initiate: initiate,\n get: get,\n getOne: getOne,\n list: list,\n save: save,\n saveOne: saveOne,\n saveAll: saveAll,\n remove: remove,\n removeAll: removeAll,\n add: add,\n constructor: constructor,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n saveByFilter: saveByFilter,\n removeByFilter: removeByFilter\n };\n /**\r\n * initiate type and callback\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @memberof GenericService\r\n */\n\n function initiate(type, callback) {\n objectType = type;\n objectCallback = callback;\n }\n /**\r\n * Get the requested object\r\n * @memberof GenericService\r\n * @param {number} id The unique identifier\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} result\r\n */\n\n\n function get(id, type, callback) {\n initiate(type, callback);\n var objects = list(type, callback);\n if (objects == null) return null;\n var result = null;\n var arrayLength = objects.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (objects[i].GetId() == id) {\n result = objects[i];\n break;\n }\n }\n\n return result;\n }\n /**\r\n * Get all the objects\r\n * @memberof GenericService\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {array} objectList\r\n */\n\n\n function list(type, callback) {\n initiate(type, callback);\n var objects = localStorageMD5Service.get(objectType);\n return fromObjectList(objects, callback);\n }\n /**\r\n * Get the unique object of this storage\r\n * @memberof GenericService\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} result\r\n */\n\n\n function getOne(type, callback) {\n initiate(type, callback);\n var object = localStorageMD5Service.get(objectType);\n return fromObject(object, callback);\n }\n /**\r\n * Save the unique object of this storage\r\n * @memberof GenericService\r\n * @param {object} obj The object to save\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\\\r\n */\n\n\n function saveOne(obj, type, callback) {\n localStorageMD5Service.set(type, obj);\n }\n /**\r\n * update the object\r\n * @memberof GenericService\r\n * @param {object} object The object to save\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\\\r\n */\n\n\n function save(object, type, callback) {\n initiate(type, callback);\n var objects = list(type, callback);\n var updatedobject = fromObject(object, callback);\n var arrayLength = objects.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (objects[i].GetId() == updatedobject.GetId()) {\n objects[i] = updatedobject;\n break;\n }\n }\n\n saveAll(objects, type, callback);\n }\n /**\r\n * Save the objects \r\n * @memberof GenericService\r\n * @param {array} objects The objects to save\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\\\r\n */\n\n\n function saveAll(objects, type, callback) {\n initiate(type, callback);\n localStorageMD5Service.set(objectType, objects);\n }\n /**\r\n * remove the object based on its unique identifier\r\n * @memberof GenericService\r\n * @param {number} Id The unique identifier\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n */\n\n\n function remove(Id, type, callback) {\n initiate(type, callback);\n var objects = list(type, callback);\n var newObjects = [];\n var arrayLength = objects.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (objects[i].GetId() != Id) {\n newObjects.push(objects[i]);\n }\n }\n\n saveAll(newObjects, type, callback);\n }\n /**\r\n * remove all the objects\r\n * @memberof GenericService\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n */\n\n\n function removeAll(type, callback) {\n initiate(type, callback);\n localStorageMD5Service.remove(objectType);\n }\n /**\r\n * add the object\r\n * @memberof GenericService\r\n * @param {object} object The object to save\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n */\n\n\n function add(obj, type, callback) {\n var objects = list(type, callback);\n objects.push(obj);\n saveAll(objects, type, callback);\n }\n /**\r\n * Create a new object\r\n * @memberof GenericService\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} object\r\n */\n\n\n function constructor(callback) {\n var object = new callback();\n return object;\n }\n /**\r\n * Extend given object \r\n * @memberof GenericService\r\n * @param {object} obj The object that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} object\r\n */\n\n\n function fromObject(obj, callback) {\n if (obj == null) return null;\n var object = new callback();\n angular.extend(object, obj);\n return object;\n }\n\n ;\n /**\r\n * Extend given object list\r\n * @memberof GenericService\r\n * @param {array} objList The list of objects that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} objList\r\n */\n\n function fromObjectList(objList, callback) {\n if (objList == null) return [];\n var arrayLength = objList.length;\n var objects = new Array();\n\n for (var i = 0; i < arrayLength; i++) {\n objects.push(fromObject(objList[i], callback));\n }\n\n return objects;\n }\n\n ;\n /**\r\n * Update object in local storage - Search it by filters\r\n * @param {object} object The objects to save\r\n * @param {array} filters Array of property-value pairs to act as ids \r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n */\n\n function saveByFilter(object, filters, type, callback) {\n initiate(type, callback);\n var objects = list(type, callback);\n var updatedobject = fromObject(object, callback);\n var arrayLength = objects.length;\n\n for (var j = 0; j < arrayLength; j++) {\n var retVal = true;\n var storageObject = objects[j];\n\n for (var i = 0; i < filters.length; i++) {\n if (storageObject[filters[i][0]] != filters[i][1]) {\n retVal = false;\n break;\n }\n }\n\n if (retVal) {\n objects[j] = updatedobject;\n break;\n }\n }\n\n saveAll(objects, type, callback);\n }\n /**\r\n * Remove object from local strage - Search it by filters\r\n * @param {array} filters Array of property-value pairs to act as ids \r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n */\n\n\n function removeByFilter(filters, type, callback) {\n initiate(type, callback);\n var objects = list(type, callback);\n var newObjects = [];\n var arrayLength = objects.length;\n\n for (var j = 0; j < arrayLength; j++) {\n var storageObject = objects[j];\n\n for (var i = 0; i < filters.length; i++) {\n if (storageObject[filters[i][0]] != filters[i][1]) {\n newObjects.push(storageObject);\n break;\n }\n }\n }\n\n saveAll(newObjects, type, callback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('GenericValuesFactory', GenericValuesFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name GenericValuesFactory\r\n * @description \r\n * Generic add, edit or remove for list of values\r\n * @ngInject\r\n */\n\n function GenericValuesFactory(localStorageMD5Service) {\n var service = {\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n objList: objList,\n getValuesFromStorage: getValuesFromStorage,\n setValuesToStorage: setValuesToStorage,\n clearValuesFromStorage: clearValuesFromStorage,\n getValuesFromStorageAsStrings: getValuesFromStorageAsStrings\n };\n /**\r\n * Extend given object \r\n * @memberof GenericValuesFactory\r\n * @param {object} obj The object that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} object\r\n */\n\n function fromObject(obj, callback) {\n if (obj == null) return null;\n var newObj = new callback();\n newObj.Code = obj;\n return newObj;\n }\n\n ;\n /**\r\n * Extend given object list\r\n * @memberof GenericValuesFactory\r\n * @param {array} objList The list of objects that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} objList\r\n */\n\n function fromObjectList(objList, callback) {\n if (objList == null) return null;\n var arrayLength = objList.length;\n var newObjList = [];\n\n for (var i = 0; i < arrayLength; i++) {\n var newObj = new callback();\n newObj.Code = objList[i];\n newObjList.push(newObj);\n }\n\n return newObjList;\n }\n\n ;\n /**\r\n * Get all the object's Code from given list\r\n * @memberof GenericValuesFactory\r\n * @param {array} objectList An object list\r\n * @returns {array} objectList\r\n */\n\n function objList(objList) {\n if (objList == null) return [];\n var arrayLength = objList.length;\n var newObjList = [];\n\n for (var i = 0; i < arrayLength; i++) {\n newObjList.push(objList[i].Code);\n }\n\n return newObjList;\n }\n\n ;\n /**\r\n * Get all the objects\r\n * @memberof GenericValuesFactory\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {array} objectList\r\n */\n\n function getValuesFromStorage(callback, type) {\n var objects = localStorageMD5Service.get(type);\n return fromObjectList(objects, callback);\n }\n /**\r\n * Set all the objects\r\n * @memberof GenericValuesFactory\r\n * @param {array} objects A list of objects.\r\n * @param {string} type A string which identifies the local storage name\r\n */\n\n\n function setValuesToStorage(objects, type) {\n localStorageMD5Service.set(type, objects);\n }\n /**\r\n * Remove all the objects\r\n * @memberof GenericValuesFactory\r\n * @param {string} type A string which identifies the local storage name\r\n */\n\n\n function clearValuesFromStorage(type) {\n localStorageMD5Service.remove(type);\n }\n /**\r\n * Get all the objects codes from local storage\r\n * @memberof GenericValuesFactory\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {array} objectList\r\n */\n\n\n function getValuesFromStorageAsStrings(callback, type) {\n var result = [];\n var objs = getValuesFromStorage(callback, type);\n\n if (objs != null || objs != undefined) {\n for (var i = 0; i < objs.length; i++) {\n result.push(objs[i].Code);\n }\n }\n\n return result;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('IndexedDBService', IndexedDBService);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name IndexedDBService\r\n * @description \r\n * Generic add, edit or remove for IndexedDB\r\n * @ngInject\r\n */\n\n function IndexedDBService($q, LogService) {\n var idbSupported = \"indexedDB\" in window;\n\n if (!idbSupported) {\n LogService.debug(\"No IndexedDb is supported for this browser's version\");\n }\n\n return {\n /**\r\n * initiate or update indexedDB storage\r\n * @memberof IndexedDBService\r\n * @returns {object} promise\r\n */\n init: function init() {\n var deferred = $q.defer();\n var request = indexedDB.open(\"a3.cabin.reports\", 10);\n\n request.onupgradeneeded = function (e) {\n // The database did not previously exist, so create object stores and indexes.\n var db = request.result;\n\n if (e.oldVersion < 1) {\n var gameStore = db.createObjectStore(\"Memos\", {\n keyPath: \"Id\"\n });\n gameStore.createIndex(\"id_idx\", \"Id\", {\n unique: true\n });\n }\n\n if (e.oldVersion < 2) {\n var gameStore1 = db.createObjectStore(\"MemoImages\", {\n keyPath: \"imageId\"\n });\n gameStore1.createIndex(\"id_idx\", \"imageId\", {\n unique: true\n });\n gameStore1.createIndex(\"memoId\", \"memoId\", {\n unique: false\n });\n }\n\n if (e.oldVersion < 5 && !db.objectStoreNames.contains('PaxInfo')) {\n var gameStore2 = db.createObjectStore(\"PaxInfo\", {\n keyPath: \"FlightId\"\n });\n gameStore2.createIndex(\"id_idx\", \"FlightId\", {\n unique: true\n });\n }\n\n if (e.oldVersion <= 6 && !db.objectStoreNames.contains('Reports')) {\n var gameStore3 = db.createObjectStore(\"Reports\", {\n keyPath: \"FlightId\"\n });\n gameStore3.createIndex(\"id_idx\", \"FlightId\", {\n unique: true\n });\n }\n\n if (e.oldVersion <= 7 && !db.objectStoreNames.contains('Courses')) {\n var gameStore3 = db.createObjectStore(\"Courses\", {\n keyPath: \"Id\"\n });\n gameStore3.createIndex(\"id_idx\", \"Id\", {\n unique: true\n });\n var store4 = db.createObjectStore(\"TrainingSessions\", {\n keyPath: ['day', 'courseId', 'dutyId']\n });\n store4.createIndex(\"id_idx\", ['day', 'courseId', 'dutyId'], {\n unique: true\n });\n store4.createIndex(\"day_idx\", \"day\", {\n unique: false\n });\n store4.createIndex(\"courseId_idx\", \"courseId\", {\n unique: false\n });\n }\n\n if (e.oldVersion <= 8 && !db.objectStoreNames.contains('FlightSessions')) {\n var store = db.createObjectStore(\"FlightSessions\", {\n keyPath: ['day', 'courseId', 'dutyNo', 'dutyDay']\n });\n store.createIndex(\"id_idx\", ['day', 'courseId', 'dutyNo', 'dutyDay'], {\n unique: true\n });\n store.createIndex(\"day_idx\", \"day\", {\n unique: false\n });\n store.createIndex(\"courseId_idx\", \"courseId\", {\n unique: false\n });\n }\n\n if (e.oldVersion <= 9 && !db.objectStoreNames.contains('ToolkitItems')) {\n var gameStore2 = db.createObjectStore(\"ToolkitItems\", {\n keyPath: \"Id\"\n });\n gameStore2.createIndex(\"id_idx\", \"Id\", {\n unique: true\n });\n }\n\n if (e.oldVersion <= 10 && !db.objectStoreNames.contains('PassengerMealServices')) {\n var gameStore = db.createObjectStore(\"PassengerMealServices\", {\n keyPath: \"Id\"\n });\n gameStore.createIndex(\"id_idx\", \"Id\", {\n unique: true\n });\n }\n };\n\n request.onsuccess = function () {\n deferred.resolve(request.result);\n };\n\n request.onerror = function () {\n LogService.error(request.error);\n deferred.reject(request.error);\n };\n\n return deferred.promise;\n },\n deleteDatabase: function deleteDatabase(callback) {\n var deferred = $q.defer();\n var request = indexedDB.deleteDatabase(\"a3.cabin.reports\");\n\n request.onsuccess = function () {\n deferred.resolve();\n };\n\n request.onerror = function (ex) {\n deferred.reject(ex);\n };\n\n request.onabort = function (ex) {\n deferred.reject(ex);\n };\n\n return deferred.promise;\n },\n info: function info(storeName) {\n var deferred = $q.defer();\n\n var info = function info(db) {\n var tx = db.transaction([storeName], \"readonly\");\n var store = tx.objectStore(storeName);\n store.indexNames;\n store.keyPath;\n var indexes = \"No indexes Found\";\n\n if (store.indexNames && store.indexNames.length > 0) {\n indexes = \"Indexes :: \";\n\n for (var i = 0; i < store.indexNames.length; i++) {\n if (i < store.indexNames.length - 1) {\n indexes = indexes + store.indexNames[i] + \",\";\n } else {\n indexes = indexes + store.indexNames[i];\n }\n }\n }\n\n var keypath = store.keyPath ? \"Keypath :: \" + store.keyPath : \"No keypath\";\n var errorMsg = \"Store ::\" + storeName + \" - \" + indexes + \" - \" + keypath;\n LogService.debug(errorMsg);\n\n tx.oncomplete = function (e) {\n // All requests have succeeded and the transaction has committed.\n deferred.resolve();\n };\n\n tx.onerror = function (ex) {\n deferred.reject(ex);\n };\n\n tx.onabort = function (ex) {\n deferred.reject(ex);\n };\n };\n\n if (idbSupported) {\n this.init().then(info);\n } else {\n deferred.resolve();\n }\n\n return deferred.promise;\n },\n\n /**\r\n * Add the object\r\n * @memberof IndexedDBService\r\n * @param {string} storeName A string which identifies the IndexedDB storage\r\n * @param {object} entity The object to add\r\n * @returns {object} promise\r\n */\n add: function add(storeName, entity) {\n var deferred = $q.defer();\n\n var add = function add(db) {\n var tx = db.transaction([storeName], \"readwrite\");\n var store = tx.objectStore(storeName);\n store.add(entity);\n\n tx.oncomplete = function (e) {\n // All requests have succeeded and the transaction has committed.\n deferred.resolve(entity.id);\n };\n\n tx.onerror = function (ex) {\n deferred.reject(ex);\n };\n\n tx.onabort = function (ex) {\n deferred.reject(ex);\n };\n };\n\n if (idbSupported) {\n this.init().then(add);\n } else {\n deferred.resolve();\n }\n\n return deferred.promise;\n },\n\n /**\r\n * Add all the objects\r\n * @memberof IndexedDBService\r\n * @param {string} storeName A string which identifies the IndexedDB storage\r\n * @param {array} entity The objects to add\r\n * @returns {object} promise\r\n */\n addAll: function addAll(storeName, entity) {\n var deferred = $q.defer();\n\n var add = function add(db) {\n var tx = db.transaction([storeName], \"readwrite\");\n var store = tx.objectStore(storeName);\n var count = 0; //Insert several objects: [{obj},{obj},{obj}]\n\n for (var i = 0; i < entity.length; i++) {\n store.add(entity[i]);\n count++;\n }\n\n tx.oncomplete = function (e) {\n // All requests have succeeded and the transaction has committed.\n deferred.resolve(count);\n };\n\n tx.onerror = function (ex) {\n deferred.reject(ex);\n };\n\n tx.onabort = function (ex) {\n deferred.reject(ex);\n }; //db.close();\n\n };\n\n if (idbSupported) {\n this.init().then(add);\n } else {\n deferred.resolve();\n }\n\n return deferred.promise;\n },\n\n /**\r\n * update object\r\n * @memberof IndexedDBService\r\n * @param {string} storeName A string which identifies the IndexedDB storage\r\n * @param {array} entity The object to update\r\n * @returns {object} promise\r\n */\n put: function put(storeName, entity) {\n var deferred = $q.defer();\n\n var put = function put(db) {\n var tx = db.transaction([storeName], \"readwrite\");\n var store = tx.objectStore(storeName);\n store.put(entity);\n\n tx.oncomplete = function () {\n // All requests have succeeded and the transaction has committed.\n deferred.resolve(tx.result);\n };\n\n tx.onerror = function () {\n deferred.reject(tx);\n };\n\n tx.onabort = function () {\n deferred.reject(tx);\n };\n };\n\n if (idbSupported) {\n this.init().then(put);\n } else {\n deferred.resolve();\n }\n\n return deferred.promise;\n },\n\n /**\r\n * Get the requested object by the default index\r\n * @memberof IndexedDBService\r\n * @param {string} storeName A string which identifies the IndexedDB storage\r\n * @param {number} id The unique identifier\r\n * @returns {object} promise\r\n */\n getById: function getById(storeName, id) {\n var deferred = $q.defer();\n\n var getById = function getById(db) {\n var tx = db.transaction([storeName], \"readonly\");\n var store = tx.objectStore(storeName);\n var index = store.index(\"id_idx\");\n var request = index.get(id);\n\n request.onsuccess = function () {\n deferred.resolve(request.result);\n };\n\n request.onerror = function () {\n deferred.reject(request.error);\n };\n\n tx.onabort = function () {\n deferred.reject(tx.error);\n };\n };\n\n if (idbSupported) {\n this.init().then(getById);\n } else {\n deferred.resolve(null);\n }\n\n return deferred.promise;\n },\n\n /**\r\n * Get the requested object by the selected index\r\n * @memberof IndexedDBService\r\n * @param {string} storeName A string which identifies the IndexedDB storage\r\n * @param {string} indexName A string which identifies the index name\r\n * @param {number} id The unique identifier\r\n * @returns {object} promise\r\n */\n getByIndex: function getByIndex(storeName, indexName, value) {\n var deferred = $q.defer();\n\n var getByIndex = function getByIndex(db) {\n var tx = db.transaction([storeName], \"readonly\");\n var store = tx.objectStore(storeName);\n var index = store.index(indexName);\n var request = index.openCursor(IDBKeyRange.only(value)); //IDBKeyRange.only(value)\n\n var results = [];\n\n request.onsuccess = function () {\n var cursor = request.result;\n\n if (cursor) {\n results.push(cursor.value);\n cursor[\"continue\"]();\n } else {\n deferred.resolve(results);\n }\n };\n\n request.onerror = function (r) {\n deferred.reject(r.error);\n };\n\n tx.onabort = function (r) {\n deferred.reject(r.error);\n };\n };\n\n if (idbSupported) {\n this.init().then(getByIndex);\n } else {\n deferred.resolve(null);\n }\n\n return deferred.promise;\n },\n\n /**\r\n * Get the all objects of the selected store\r\n * @memberof IndexedDBService\r\n * @param {string} storeName A string which identifies the IndexedDB storage\r\n * @param {string} indexName A string which identifies the index name (optional)\r\n * @returns {object} promise\r\n */\n getAll: function getAll(storeName, indexName) {\n var deferred = $q.defer();\n if (indexName === undefined) indexName = 'id_idx';\n\n var all = function all(db) {\n var tx = db.transaction([storeName], \"readonly\");\n var store = tx.objectStore(storeName); //var index = store.index(indexName);\n\n var request = store.openCursor(); //IDBKeyRange.only(\"Fred\")\n\n var results = [];\n\n request.onsuccess = function () {\n var cursor = request.result;\n\n if (cursor) {\n results.push(cursor.value);\n cursor[\"continue\"]();\n } else {\n deferred.resolve(results);\n }\n };\n\n request.onerror = function () {\n LogService.error(request.error);\n deferred.reject(request.error);\n };\n\n tx.onabort = function () {\n deferred.reject(tx.error);\n };\n };\n\n if (idbSupported) {\n this.init().then(all);\n } else {\n deferred.resolve([]);\n }\n\n return deferred.promise;\n },\n\n /**\r\n * Count all objects of the selected store\r\n * @memberof IndexedDBService\r\n * @param {string} storeName A string which identifies the IndexedDB storage\r\n * @param {string} indexName A string which identifies the index name (optional)\r\n * @returns {object} promise\r\n */\n count: function count(storeName, indexName) {\n var deferred = $q.defer();\n if (indexName === undefined) indexName = 'id_idx';\n\n var count = function count(db) {\n var tx = db.transaction([storeName], \"readonly\");\n var store = tx.objectStore(storeName);\n var index = store.index(indexName);\n var request = index.count();\n\n request.onsuccess = function () {\n deferred.resolve(request.result);\n };\n\n request.onerror = function () {\n deferred.reject(request.error);\n };\n\n tx.onabort = function () {\n deferred.reject(tx.error);\n };\n };\n\n if (idbSupported) {\n this.init().then(count);\n } else {\n deferred.resolve(0);\n }\n\n return deferred.promise;\n },\n\n /**\r\n * Delete the requested object\r\n * @memberof IndexedDBService\r\n * @param {string} storeName A string which identifies the IndexedDB storage\r\n * @param {number} id The unique identifier\r\n * @returns {object} promise\r\n */\n remove: function remove(storeName, id) {\n var deferred = $q.defer();\n\n var remove = function remove(db) {\n var tx = db.transaction([storeName], \"readwrite\");\n var store = tx.objectStore(storeName);\n store[\"delete\"](id);\n\n tx.oncomplete = function (e) {\n // All requests have succeeded and the transaction has committed.\n deferred.resolve(id);\n };\n\n tx.onerror = function (r) {\n deferred.reject(r.error);\n };\n\n tx.onabort = function (r) {\n deferred.reject(r.error);\n };\n };\n\n if (idbSupported) {\n this.init().then(remove);\n } else {\n deferred.resolve();\n }\n\n return deferred.promise;\n },\n\n /**\r\n * Delete the requested object by the selected index\r\n * @memberof IndexedDBService\r\n * @param {string} storeName A string which identifies the IndexedDB storage\r\n * @param {string} indexName A string which identifies the index name (optional)\r\n * @param {number} id The unique identifier\r\n * @returns {object} promise\r\n */\n removeByIndex: function removeByIndex(storeName, indexName, value) {\n var deferred = $q.defer();\n\n var removeByIndex = function removeByIndex(db) {\n var tx = db.transaction([storeName], \"readwrite\");\n var store = tx.objectStore(storeName);\n var index = store.index(indexName);\n var request = index.openKeyCursor(IDBKeyRange.only(value)); //IDBKeyRange.only(value)\n\n var results = [];\n\n request.onsuccess = function () {\n var cursor = request.result;\n\n if (cursor) {\n store[\"delete\"](cursor.primaryKey);\n cursor[\"continue\"]();\n } else {\n deferred.resolve(results);\n }\n };\n\n request.onerror = function (r) {\n deferred.reject(r.error);\n };\n\n tx.onabort = function (r) {\n deferred.reject(r.error);\n };\n };\n\n if (idbSupported) {\n this.init().then(removeByIndex);\n } else {\n deferred.resolve();\n }\n\n return deferred.promise;\n },\n\n /**\r\n * Delete all the objects\r\n * @memberof IndexedDBService\r\n * @param {string} storeName A string which identifies the IndexedDB storage\r\n * @returns {object} promise\r\n */\n removeAll: function removeAll(storeName) {\n var deferred = $q.defer();\n\n var remove = function remove(db) {\n var tx = db.transaction([storeName], \"readwrite\");\n var store = tx.objectStore(storeName);\n store.clear();\n\n tx.oncomplete = function (e) {\n // All requests have succeeded and the transaction has committed.\n deferred.resolve('success');\n };\n\n tx.onerror = function (r) {\n deferred.reject(r.error);\n };\n\n tx.onabort = function (r) {\n deferred.reject(r.error);\n }; //db.close();\n\n };\n\n if (idbSupported) {\n this.init().then(remove);\n } else {\n deferred.resolve();\n }\n\n return deferred.promise;\n }\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('ModalDialogResultFactory', ModalDialogResultFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ModalDialogResultFactory\r\n * @description \r\n * Modal Dialog Creator\r\n * @ngInject\r\n */\n\n function ModalDialogResultFactory() {\n /**\r\n * Initialize the ModalDialogResult\r\n * @memberof ModalDialogResultFactory\r\n */\n function ModalDialogResult() {\n this.IsInsertMode = null;\n this.Object = null;\n }\n\n var service = {\n createNew: createNew\n };\n /**\r\n * Create a new ModalDialogResult object\r\n * @memberof ModalDialogResultFactory\r\n * @returns {object} object\r\n */\n\n function createNew() {\n return new ModalDialogResult();\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.service(\"PushNotifier\", PushNotifier);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc service\r\n * @name PushNotifier\r\n * @description \r\n * Push notification functionality\r\n * @ngInject\r\n */\n\n function PushNotifier($q, FlightFactory, PaxInfoFactory) {\n var service = {\n Generate: Generate,\n formatInfoToCompare: formatInfoToCompare,\n compareAndExtractChanges: compareAndExtractChanges,\n MessageGenerator: BodyGenerator,\n CheckForPermissionsAndSupport: CheckForPermissionsAndSupport\n };\n var browserSupportsNotifications = \"Notification\" in window;\n\n function CheckForPermissionsAndSupport() {\n var deferred = $q.defer(); // Let's check if the browser supports notifications\n\n if (!browserSupportsNotifications) {\n console.debug(\"This browser does not support system notifications\");\n deferred.resolve(false);\n } // // Otherwise, we need to ask the user for permission\n\n\n if (browserSupportsNotifications && Notification.permission !== 'denied') {\n var permissionQ = Notification.requestPermission();\n\n if (permissionQ) {\n permissionQ.then(function (result) {\n var value = result === \"granted\";\n deferred.resolve(value);\n }), function (reason) {\n LogService.error(reason);\n deferred.reject(reason);\n };\n } else {\n deferred.resolve(false);\n }\n } else {\n deferred.resolve(false);\n }\n\n return deferred.promise;\n }\n\n function Generate(title, body) {\n // Let's check whether notification permissions have already been granted\n if (browserSupportsNotifications && Notification.permission === \"granted\") {\n // If it's okay let's create a notification\n var notification = new Notification(title, {\n body: body,\n icon: './img/a3_logo.png'\n });\n setTimeout(function () {\n notification.close();\n }, 5000);\n }\n }\n\n function formatInfoToCompare(flightId) {\n var flightInfo = FlightFactory.getFlightFromStorage(flightId);\n var data = {\n CTOT: flightInfo.CTOT,\n ATD: flightInfo.ATD,\n ETA: flightInfo.ETA,\n ETD: flightInfo.ETD\n };\n data['Departure Gate'] = flightInfo.DepartureGate;\n data['Departure Stand'] = flightInfo.DepartureStand;\n data['Scheduled Departure Time UTC'] = flightInfo.ScheduledDepartureTimeUTC;\n var deferred = $q.defer();\n PaxInfoFactory.getPaxInfoFromStorage(flightId, function (paxinfo) {\n data['Passenger Info'] = paxinfo ? moment.utc(paxinfo.LastRun).format('dd-MM-yyyy HH:mm') : null;\n deferred.resolve(data);\n });\n return deferred.promise;\n }\n\n function compareAndExtractChanges(currentData, updatedData) {\n var changes = [];\n\n for (var key in currentData) {\n if (currentData[key] != updatedData[key]) {\n var ovalue = currentData[key];\n var nvalue = updatedData[key];\n\n if (key === \"CTOT\" || key === \"ATD\" || key === \"ETA\" || key === \"ETD\" || key === \"Scheduled Departure Time UTC\") {\n if (currentData[key] != null) {\n ovalue = moment.utc(currentData[key]).format('HH:mm');\n }\n\n if (updatedData[key] != null) {\n nvalue = moment.utc(updatedData[key]).format('HH:mm');\n }\n }\n\n changes.push({\n type: key,\n oldValue: ovalue,\n newValue: nvalue\n });\n }\n }\n\n return changes;\n }\n\n function BodyGenerator(changes) {\n var message = '';\n changes.forEach(function (x) {\n var phrase = null;\n\n if (x.type == 'Passenger Info') {\n phrase = \"Passenger Info have been updated. \\n\";\n } else if (!x.oldValue) {\n phrase = x.type + \": \" + x.newValue + \" \\n\";\n } else if (x.oldValue && x.newValue) {\n phrase = x.type + \": \" + x.oldValue + \"\\u2192\" + x.newValue + \" \\n\";\n } else {\n phrase = x.type + \" has no value\\n\";\n }\n\n message = message + phrase;\n });\n return message;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.filter('search', search);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc filter\r\n * @name search\r\n * @description \r\n * @ngInject\r\n */\n\n function search() {\n /**\r\n * Filter available toolkit items by search text\r\n * @param {array} itemArray Array to be filtered\r\n * @param {string} text Search text input \r\n */\n return function (itemArray, text) {\n if (!itemArray || text == undefined || text == null) {\n return [];\n }\n\n if (!text.length) {\n return itemArray;\n }\n\n var searchRegex = /[ ,;]+/;\n var searchWords = text.toLowerCase().split(searchRegex);\n searchWords = searchWords.filter(function (x) {\n return x.length > 0;\n }); //FOR FUTURE: Add Dynamic fields for search\n\n return itemArray.filter(function (x) {\n return searchWords.some(function (y) {\n return x.Title.toLowerCase().includes(y);\n }) || searchWords.some(function (y) {\n return x.Description.toLowerCase().includes(y);\n }) || searchWords.some(function (y) {\n return x.Comments && x.Comments.toLowerCase().includes(y);\n }) || searchWords.some(function (y) {\n return x.Tags.some(function (t) {\n return t.toLowerCase().includes(y);\n });\n });\n });\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('SettingsMain', SettingsMain);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SettingsMain\r\n * @description \r\n * Generic add, edit or remove\r\n * @ngInject\r\n */\n\n function SettingsMain($log, localStorageMD5Service, FlightFactory) {\n /**\r\n * Initialize the PageMainSettings\r\n * @memberof SettingsMain\r\n */\n function PageMainSettings() {\n this.EditingPage = null;\n this.IsAssessmentEnabled = null;\n this.calendarViewStyle = null;\n this.selectedDate = null;\n }\n\n var service = {\n getSettings: getSettings,\n setSettings: setSettings,\n getEditingPage: getEditingPage,\n setEditingPage: setEditingPage,\n getIsAssessmentEnabled: getIsAssessmentEnabled,\n setIsAssessmentEnabled: setIsAssessmentEnabled,\n setCalendarViewStyle: setCalendarViewStyle,\n getCalendarViewStyle: getCalendarViewStyle,\n getCalendarSelectedDate: getCalendarSelectedDate,\n setCalendarSelectedDate: setCalendarSelectedDate\n }; //factory functions\n\n /**\r\n * Get Application Settings\r\n * @memberof SettingsMain\r\n * @returns {object} settings \r\n */\n\n function getSettings() {\n var settings = new PageMainSettings();\n var settingsStored = localStorageMD5Service.get('settingsMain');\n\n if (settingsStored) {\n if (settingsStored.EditingPage) settings.EditingPage = settingsStored.EditingPage;\n settings.IsAssessmentEnabled = settingsStored.IsAssessmentEnabled;\n settings.calendarViewStyle = settingsStored.calendarViewStyle;\n settings.selectedDate = settingsStored.selectedDate;\n }\n\n return settings;\n }\n /**\r\n * Set Application Settings\r\n * @param {object} settings\r\n * @memberof SettingsMain\r\n */\n\n\n function setSettings(settings) {\n localStorageMD5Service.set('settingsMain', settings);\n }\n /**\r\n * Get editing page\r\n * @memberof SettingsMain\r\n * @returns {string} EditingPage\r\n */\n\n\n function getEditingPage() {\n var settings = getSettings();\n return settings.EditingPage;\n }\n /**\r\n * Set editing page\r\n * @param {string} value\r\n * @memberof SettingsMain\r\n */\n\n\n function setEditingPage(value) {\n var settings = getSettings();\n settings.EditingPage = value;\n setSettings(settings);\n }\n /**\r\n * Get if assessment is enabled\r\n * @memberof SettingsMain\r\n * @returns {boolean} isEnabled\r\n */\n\n\n function getIsAssessmentEnabled() {\n var settings = getSettings();\n var isEnabled = settings.IsAssessmentEnabled;\n\n if (isEnabled) {\n var flights = FlightFactory.getFlightsFromStorage();\n\n if (flights) {\n for (var i = 0; i < flights.length; i++) {\n if ((flights[i].AcType == 'DH4' || flights[i].AcType == 'DH8' || flights[i].AcType == 'AT4') && flights[i].isDHC) {\n isEnabled = false;\n break;\n }\n }\n }\n }\n\n return isEnabled;\n }\n /**\r\n * Set if assessment is enabled\r\n * @param {string} value\r\n * @memberof SettingsMain\r\n */\n\n\n function setIsAssessmentEnabled(value) {\n var settings = getSettings();\n settings.IsAssessmentEnabled = value;\n setSettings(settings);\n }\n /**\r\n * Get prefered calendar view style\r\n * @memberof SettingsMain\r\n * @returns {string} viewStyle\r\n */\n\n\n function getCalendarViewStyle() {\n var settings = getSettings();\n var viewStyle = settings.calendarViewStyle;\n return viewStyle;\n }\n /**\r\n * Set prefered calendar view style\r\n * @param {string} value\r\n * @memberof SettingsMain\r\n */\n\n\n function setCalendarViewStyle(value) {\n var settings = getSettings();\n settings.calendarViewStyle = value;\n setSettings(settings);\n }\n /**\r\n * Get selected calendar date\r\n * @memberof SettingsMain\r\n * @returns {string} selectedDate\r\n */\n\n\n function getCalendarSelectedDate() {\n var settings = getSettings();\n var selectedDate = settings.selectedDate;\n return selectedDate;\n }\n /**\r\n * Set selected calendar date\r\n * @param {string} value\r\n * @memberof SettingsMain\r\n */\n\n\n function setCalendarSelectedDate(value) {\n var settings = getSettings();\n settings.selectedDate = value;\n setSettings(settings);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('TimeLogFactory', TimeLogFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name TimeLogFactory\r\n * @description \r\n * Get list, Update list & Acknowledge schedule changes\r\n * @ngInject\r\n */\n\n function TimeLogFactory(GenericService) {\n /**\r\n * Initialize the ScheduleChanges\r\n * @memberof TimeLogFactory\r\n */\n function TimeLog() {\n this.Date = null;\n this.ClientTimeLog = \"\";\n this.ApiTimeLog = \"\";\n }\n\n var objType = 'timeLogs';\n var objCallback = TimeLog;\n var service = {\n timeLogToStorage: timeLogToStorage,\n cleanOldData: cleanOldData\n };\n /**\r\n * Save all time logs to storage\r\n * @memberof TimeLogFactory\r\n * @param {Array} CrewPhoneNumbers\r\n */\n\n function setTimeLogsToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * get all time logs from storage\r\n * @memberof TimeLogFactory\r\n */\n\n\n function getTimeLogsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save the time log to storage\r\n * @memberof TimeLogFactory\r\n * @param clientTimeLog \r\n * @param apiTimeLog \r\n */\n\n\n function timeLogToStorage(timeLogStr, apiTimelog) {\n var timeLog = new TimeLog();\n timeLog.Date = moment.utc();\n timeLog.ClientTimeLog = timeLogStr;\n timeLog.ApiTimeLog = apiTimelog;\n GenericService.add(timeLog, objType, objCallback);\n }\n /**\r\n * Clean old time logs\r\n */\n\n\n function cleanOldData() {\n var now = moment();\n var timeLogs = getTimeLogsFromStorage();\n var latestTimeLogs = []; //Filter out crew check-ins of old flights\n\n timeLogs.forEach(function (x) {\n var date = moment(x.Date);\n\n if (now.diff(date, 'days') < 2) {\n latestTimeLogs.push(x);\n }\n });\n setTimeLogsToStorage(latestTimeLogs);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.service(\"UpdateService\", UpdateService);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc service\r\n * @name UpdateService\r\n * @description \r\n * Update functionality\r\n * @ngInject\r\n */\n\n function UpdateService(SyncLogFactory) {\n /**\r\n * Version patcher\r\n * @memberof UpdateService\r\n * @returns {string} NeedsSync \r\n */\n function patcher(version) {\n var NeedsSync = false;\n\n if (version == \"1.0\") {\n SyncLogFactory.updateSyncVersion(\"1.1\"); //patching to next version\n\n patcher(\"1.1\");\n NeedsSync = true;\n } else if (version == \"1.1\") {\n SyncLogFactory.updateSyncVersion(\"1.2\"); //patching to next version\n //patcher(\"1.2\");\n\n NeedsSync = true;\n }\n\n return NeedsSync;\n }\n\n return {\n /**\r\n * updates application \r\n * @memberof UpdateService\r\n * @returns {string} NeedsSync \r\n */\n updater: function updater() {\n var synclog = SyncLogFactory.getSyncLog();\n\n if (synclog == undefined || synclog == null) {\n return false;\n } else if (synclog.isUpdated) {\n return true;\n } else {\n var NeedsSync = patcher(synclog.version);\n return NeedsSync;\n }\n }\n };\n }\n})();\n\"use strict\";\n\n// create guid\nvar guid = function () {\n function s4() {\n return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);\n }\n\n return function () {\n return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();\n };\n}(); // generic sort function\n\n\nvar sort_by = function sort_by(field, reverse, primer) {\n var key = function key(x) {\n return primer ? primer(x[field]) : x[field];\n };\n\n return function (a, b) {\n var A = key(a),\n B = key(b);\n return (A < B ? -1 : A > B ? 1 : 0) * [-1, 1][+!!reverse];\n };\n}; //used to adjust textarea to fit their content\n\n\nvar autoAdjustTextarea = function autoAdjustTextarea(element) {\n try {\n if (element) {\n //element appears to have 0 scrollHeight when hidden (parent is hidden etc)\n if (element.scrollHeight > 0) {\n element.style.overflow = 'hidden';\n element.style.height = 0;\n\n if (element.scrollHeight > 40) {\n element.style.height = element.scrollHeight + 'px';\n } else {\n element.style.height = 40 + 'px';\n }\n }\n }\n } catch (e) {}\n};\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CheckInFactory', CheckInFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CheckInFactory\r\n * @description \r\n * Get list, Update list & Acknowledge schedule changes\r\n * @ngInject\r\n */\n\n function CheckInFactory(GenericService, $http, apiUrl, LogService) {\n /**\r\n * Initialize the ScheduleChanges\r\n * @memberof CheckInFactory\r\n */\n function CheckIn() {}\n\n var objType = 'CheckIn';\n var objCallback = CheckIn;\n var response = {\n success: false,\n message: '',\n checkInInfo: null\n };\n var service = {\n setCheckInInfoToStorage: setCheckInInfoToStorage,\n getCheckInInfoFromStorage: getCheckInInfoFromStorage,\n checkIn: checkIn,\n saveCheckInDelay: saveCheckInDelay\n };\n /**\r\n * Save check in info\r\n * @param {array} checkInInfo \r\n */\n\n function setCheckInInfoToStorage(checkInInfo) {\n if (checkInInfo == undefined || checkInInfo == null) {\n GenericService.removeAll(objType);\n } else {\n GenericService.saveOne(checkInInfo, objType, objCallback);\n }\n }\n /**\r\n * Get check in info\r\n */\n\n\n function getCheckInInfoFromStorage() {\n return GenericService.getOne(objType, objCallback);\n ;\n }\n /**\r\n * Check In\r\n * @returns {promise} response\r\n */\n\n\n function checkIn(confirmed) {\n return $http.get(apiUrl + '/CrewCheckIn/CheckIn?confirmed=' + confirmed, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return updateCheckInCallBack(res);\n })[\"catch\"](function (res) {\n return checkInFailedCallBack(res);\n });\n }\n /**\r\n * Update Schedule changes dates\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} response\r\n */\n\n\n function updateCheckInCallBack(res) {\n response.success = res.data.success;\n\n if (res.data.success) {\n //update local storage\n setCheckInInfoToStorage(res.data.data);\n response.checkInInfo = res.data.data;\n\n if (response.checkInInfo && response.checkInInfo.Confirmed && response.checkInInfo.ErrorExplanation === \"\") {\n response.message = \"Success! Check In Confirmed.\";\n } else if (response.checkInInfo && !response.checkInInfo.Confirmed && response.checkInInfo.ErrorExplanation === \"\") {\n response.message = \"Ready for Check In.\";\n } else if (response.checkInInfo) {\n response.message = response.checkInInfo.ErrorExplanation;\n } else {\n response.message = \"You have not pending Check In.\";\n }\n } else {\n response.message = res.data.errorMessage;\n }\n\n return response;\n }\n /**\r\n * The callback function upon failure on submit\r\n * @returns {object} response\r\n */\n\n\n function checkInFailedCallBack(res) {\n response.success = false;\n response.message = \"Oops! Something went wrong\"; //TODO::Check status=500 error: returns res = {data: {…}, status: 500, config: {…}, statusText: \"Internal Server Error\", headers: ƒ}\n // res.data.data is null\n\n if (res.data && res.data.data) {\n response.checkInInfo = res.data.data;\n } else {\n //log results\n var responseString = JSON.stringify(res);\n LogService.error('CheckIn Failed CallBack, Response: ' + responseString);\n }\n\n return response;\n }\n /**\r\n * Save Check In Delay\r\n * @returns {promise} response\r\n */\n\n\n function saveCheckInDelay(delayMinutes) {\n var checkInInfo = getCheckInInfoFromStorage();\n checkInInfo.DelayMinutes = +delayMinutes;\n return $http.post(apiUrl + '/CrewCheckIn/SaveCheckInDelay', checkInInfo, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return updateCheckInDelayCallBack(res);\n })[\"catch\"](function (res) {\n return checkInFailedCallBack(res);\n });\n }\n\n function updateCheckInDelayCallBack(res) {\n response.success = res.data.success;\n\n if (res.data.success) {\n response.message = \"Success! Delay message was sent.\";\n } else {\n response.message = res.data.errorMessage;\n }\n\n return response;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('CheckInModalCtrl', CheckInModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CheckInModalCtrl\r\n * @description \r\n * Check in Modal\r\n * @ngInject\r\n */\n\n function CheckInModalCtrl($scope, CheckInFactory, $route, $uibModalInstance) {\n $scope.showContent = 'actions';\n $scope.cancel = cancel;\n $scope.checkInInfo = null;\n $scope.CheckInAction = CheckInAction;\n $scope.BackToActions = BackToActions;\n $scope.ConfirmCheckIn = ConfirmCheckIn;\n $scope.SendDelayMessage = SendDelayMessage;\n $scope.GetCheckInInfoFromServer = GetCheckInInfoFromServer;\n $scope.responseObj = {\n success: false,\n message: '',\n checkInInfo: null\n };\n $scope.results = [];\n $scope.selectedDelayMinutes = 10;\n $scope.onMinutesChange = onMinutesChange;\n $scope.numberDown = numberDown;\n $scope.numberUp = numberUp;\n GetCheckInInfoFromServer();\n\n function GetCheckInInfoFromServer() {\n $scope.showContent = 'loading';\n var confirmCheckIn = false;\n CheckInFactory.checkIn(confirmCheckIn).then(function (res) {\n return handleRefreshResponse(res);\n })[\"catch\"](function (res) {\n return handleRefreshResponse(res);\n });\n }\n\n function handleRefreshResponse(res) {\n $scope.showContent = 'actions';\n $scope.responseObj = res;\n }\n\n function CheckInAction() {\n $scope.showContent = 'confirm';\n }\n\n function BackToActions() {\n $scope.showContent = 'actions';\n }\n\n function ConfirmCheckIn() {\n $scope.showContent = 'loading';\n var confirmCheckIn = true;\n CheckInFactory.checkIn(confirmCheckIn).then(function (res) {\n return handleSubmitResponse(res);\n })[\"catch\"](function (res) {\n return handleSubmitResponse(res);\n });\n }\n\n function handleSubmitResponse(res) {\n $scope.showContent = 'results';\n $scope.responseObj = res;\n }\n\n function onMinutesChange(minutes) {\n $scope.selectedDelayMinutes = minutes;\n }\n\n function SendDelayMessage() {\n $scope.showContent = 'loading';\n CheckInFactory.saveCheckInDelay($scope.selectedDelayMinutes).then(function (res) {\n return handleDelayMessageResponse(res);\n })[\"catch\"](function (res) {\n return handleDelayMessageResponse(res);\n });\n }\n\n function handleDelayMessageResponse(res) {\n $scope.showContent = 'results';\n $scope.responseObj.success = res.success;\n $scope.responseObj.message = res.message;\n }\n /**\r\n * Decrease field value by 5\r\n */\n\n\n function numberDown(selectedDelayMinutes) {\n if (selectedDelayMinutes > 0) {\n $scope.selectedDelayMinutes = selectedDelayMinutes - 5;\n }\n }\n /**\r\n * Increase field value by 5\r\n */\n\n\n function numberUp(selectedDelayMinutes) {\n $scope.selectedDelayMinutes = selectedDelayMinutes + 5;\n }\n /**\r\n * Closes modal\r\n */\n\n\n function cancel() {\n $uibModalInstance.close('cancel'); // if($scope.responseObj.success){\n // $route.reload();\n // }\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('ExpiriesFactory', ExpiriesFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ExpiriesFactory\r\n * @description \r\n * Get medical & passport expiries.\r\n * @ngInject\r\n */\n\n function ExpiriesFactory(GenericService) {\n var objType = 'CrewExpiries';\n var objCallback = CrewExpiries;\n /**\r\n * Initialize the ScheduleChanges\r\n * @memberof ScheduleAcknowledgeFactory\r\n */\n\n function CrewExpiries() {\n this.expiries = [];\n this.showExpiriesModal = false;\n }\n\n var service = {\n setCrewExpiriesToStorage: setCrewExpiriesToStorage,\n getCrewExpiriesFromStorage: getCrewExpiriesFromStorage,\n showExpiriesModal: showExpiriesModal,\n showExpiriesAlert: showExpiriesAlert,\n updateShowExpiriesModal: updateShowExpiriesModal\n };\n /**\r\n * Save expiries info to storage\r\n * @param {array} objList A list of Crew Expiries\r\n */\n\n function setCrewExpiriesToStorage(objList) {\n if (objList != null) {\n var crewExpiries = {\n expiries: objList,\n showExpiriesModal: true\n };\n GenericService.saveOne(crewExpiries, objType, objCallback);\n }\n }\n /**\r\n * Get expiries info from storage\r\n */\n\n\n function getCrewExpiriesFromStorage() {\n return GenericService.getOne(objType, objCallback);\n }\n /**\r\n * Shows expiries modal\r\n * @memberof ExpiriesFactory\r\n * @returns {bool} returns the value of showExpiriesModal property\r\n */\n\n\n function showExpiriesModal() {\n var crewExpiries = getCrewExpiriesFromStorage();\n var needsReminder = false;\n\n if (crewExpiries && crewExpiries.expiries && crewExpiries.showExpiriesModal) {\n needsReminder = crewExpiries.expiries.some(function (item) {\n return (item.ExpiryTypeId == 1 || item.ExpiryTypeId == 2 || item.ExpiryTypeId == 66) && item.NeedsHardAlert;\n });\n }\n\n return needsReminder;\n }\n /**\r\n * Shows expiries alert\r\n * @memberof ExpiriesFactory\r\n * @returns {bool} returns the value of showExpiriesAlert property\r\n */\n\n\n function showExpiriesAlert() {\n var crewExpiries = getCrewExpiriesFromStorage();\n var needsAlert = false;\n\n if (crewExpiries && crewExpiries.expiries) {\n needsAlert = crewExpiries.expiries.some(function (item) {\n return (item.ExpiryTypeId == 1 || item.ExpiryTypeId == 2 || item.ExpiryTypeId == 66) && item.NeedsSoftAlert;\n });\n }\n\n return needsAlert;\n }\n /* Update expiries modal object to storage\r\n * @memberof ExpiriesFactory\r\n * @param {bool} canShowModal whether the modal can be displayed\r\n */\n\n\n function updateShowExpiriesModal(canShowModal) {\n var crewExpiries = getCrewExpiriesFromStorage();\n crewExpiries.showExpiriesModal = canShowModal;\n GenericService.saveOne(crewExpiries, objType, objCallback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('CrewCallCtrl', CrewCallCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CrewCallCtrl\r\n * @description \r\n * View confirmation warning when clicking on a crew member's telephone - Monitor call requests\r\n * @ngInject\r\n */\n\n function CrewCallCtrl($scope, $uibModalInstance, crew, flightId, groundDutyId, CrewCallFactory, UserFactory, LogCallFactory) {\n $scope.close = close;\n $scope.call = call;\n $scope.beforeCall = true;\n $scope.crewFixed = null;\n\n if (crew.id) {\n $scope.crewFixed = crew;\n } else {\n $scope.crewFixed = {\n id: crew.Id,\n name: crew.Name,\n PhoneNumber: crew.PhoneNumber\n };\n }\n /**\r\n * Close the modal\r\n */\n\n\n function close() {\n $uibModalInstance.close(false);\n }\n /**\r\n * Confirm Call\r\n */\n\n\n function call() {\n $scope.beforeCall = false;\n var user = UserFactory.getUser();\n var logData = {\n Requester: user.id,\n Requestee: $scope.crewFixed.id,\n FlightId: flightId,\n GroundDutyId: groundDutyId,\n Date: moment.utc()\n };\n\n if ($scope.isOffline) {\n //Offline: save audit to local storage, send later on sync\n LogCallFactory.saveLogCall(logData);\n } else {\n //Online : API call to save audit right now\n CrewCallFactory.LogCall(logData, function (responseData) {});\n }\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CrewCallFactory', CrewCallFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewCallFactory\r\n * @ngInject\r\n */\n\n function CrewCallFactory(GenericService, $http, apiUrl) {\n function CrewCall() {\n this.FlightId = null;\n this.CrewId = null;\n this.phoneNumber = null;\n }\n\n var objType = 'crewCall';\n var objCallback = CrewCall;\n var service = {\n getCrewCallsFromStorage: getCrewCallsFromStorage,\n setCrewCallsToStorage: setCrewCallsToStorage,\n getCrewCallFromStorage: getCrewCallFromStorage,\n getFlightCrewCallsFromStorage: getFlightCrewCallsFromStorage,\n saveCrewCall: saveCrewCall,\n cleanOldData: cleanOldData,\n LogCall: LogCall,\n cleanFlightCrewNumbers: cleanFlightCrewNumbers,\n saveFlightPhoneNumbers: saveFlightPhoneNumbers\n };\n /**\r\n * Get Crew Phone Numbers.\r\n * @memberof CrewCallFactory\r\n * @returns {Array} CrewPhoneNumbers \r\n */\n\n function getCrewCallsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Get Crew Phone Numbers for specified flight\r\n * @memberof CrewCallFactory\r\n * @param {number} flightId\r\n * @returns {Array} CrewPhoneNumbers \r\n */\n\n\n function getFlightCrewCallsFromStorage(flightId) {\n var phoneNumbers = GenericService.list(objType, objCallback);\n return phoneNumbers.filter(function (x) {\n return x.FlightId == flightId;\n });\n }\n /**\r\n * Save Crew Phone Numbers to storage\r\n * @memberof CrewCallFactory\r\n * @param {Array} CrewPhoneNumbers\r\n */\n\n\n function setCrewCallsToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Get Crew Phone Number from storage \r\n * @memberof CrewCallFactory\r\n * @param {number} crewId\r\n * @param {number} flightId\r\n * @return {object} crew phone number\r\n */\n\n\n function getCrewCallFromStorage(crewId, flightId) {\n var phoneNumbers = getCrewCallsFromStorage();\n return phoneNumbers.find(function (x) {\n return x.FlightId == flightId && x.CrewId == crewId;\n });\n }\n /**\r\n * Save a fetched crew phone number\r\n * @memberof CrewCallFactory\r\n * @param {object} crewCall \r\n */\n\n\n function saveCrewCall(crewCall) {\n GenericService.add(crewCall, objType, objCallback);\n }\n /**\r\n * Clean ls from old flight phone numbers\r\n * @param {array} flights Synced flights\r\n */\n\n\n function cleanOldData(responseFlightIds) {\n var phoneNumbers = getCrewCallsFromStorage(); //Filter out phone numbers of old flights\n\n phoneNumbers = phoneNumbers.filter(function (x) {\n return responseFlightIds.includes(x.FlightId);\n });\n var now = moment.utc();\n var keepingPhoneNumbers = [];\n phoneNumbers.forEach(function (item) {\n //Fetch FROM\n //Convert from Date UTC to Moment UTC\n var dateSTD = new Date(item.STD).fromUTC();\n var std = moment(dateSTD).utc();\n var minFetchTime = moment(std).add(-24, 'hours'); //Fetch UNTIL\n //Convert from Date UTC to Moment UTC\n\n var dateSTA = new Date(item.STA).fromUTC();\n var sta = moment(dateSTA).utc();\n var maxFetchTime = moment(sta).add(2, 'hours');\n var isAfter = now.isAfter(minFetchTime);\n var isBefore = now.isBefore(maxFetchTime);\n\n if (isAfter && isBefore) {\n keepingPhoneNumbers.push(item);\n }\n });\n setCrewCallsToStorage(keepingPhoneNumbers);\n }\n /**\r\n * Log call request\r\n * @param {string} logData Requester, Requestee, FlightId\r\n * @param {function} callback \r\n * @param {function} errorCallback \r\n */\n\n\n function LogCall(logData, callback, errorCallback) {\n return $http.post(apiUrl + '/Info/LogCrewMemberCall', logData, {\n 'Content-Type': 'application/json'\n }).then(callback)[\"catch\"](errorCallback);\n }\n /**\r\n * Clean all stored phone numbers for selected flight\r\n * @param {number} flightId \r\n */\n\n\n function cleanFlightCrewNumbers(flightId) {\n var phoneNumbers = getCrewCallsFromStorage();\n phoneNumbers = phoneNumbers.filter(function (x) {\n return x.FlightId != flightId;\n });\n setCrewCallsToStorage(phoneNumbers);\n }\n /**\r\n * Save any found crew phone numbers for specified flight\r\n * @param {number} flightId \r\n * @param {array} crew \r\n * @param {datetime} sta \r\n * @param {datetime} std \r\n */\n\n\n function saveFlightPhoneNumbers(flightId, crew, sta, std) {\n crew.forEach(function (user) {\n if (user.PhoneNumber) {\n var crewPhone = {\n FlightId: flightId,\n CrewId: user.id,\n PhoneNumber: user.PhoneNumber,\n STA: sta,\n //sta & std values will be used during sync to check timerange eligibility (-24h sta / +2h std)\n STD: std\n };\n saveCrewCall(crewPhone);\n }\n });\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('FlightCheckInsFactory', FlightCheckInsFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightCheckInsFactory\r\n * @ngInject\r\n */\n\n function FlightCheckInsFactory(GenericService) {\n function FlightCheckIn() {\n this.FlightId = null;\n this.CrewId = null;\n this.CheckIn = null;\n this.WillBeThereAt = null;\n }\n\n var objType = 'flightCheckIns';\n var objCallback = FlightCheckIn;\n var service = {\n updateFlightCrewCheckInToStorage: updateFlightCrewCheckInToStorage,\n getFlightCrewCheckInFromStorage: getFlightCrewCheckInFromStorage,\n cleanOldData: cleanOldData\n };\n /**\r\n * Get Crew Check-Ins.\r\n * @memberof CrewCallFactory\r\n * @returns {Array} CrewPhoneNumbers \r\n */\n\n function getCrewCheckInFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save crew checkIns to storage\r\n * @memberof CrewCallFactory\r\n * @param {Array} CrewPhoneNumbers\r\n */\n\n\n function setCrewCheckInToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Update Crew CheckIns for specified flight\r\n * @memberof CrewCallFactory\r\n * @param {} flight duty\r\n * @returns {Array} CrewFlightCrewCheckIns \r\n */\n\n\n function updateFlightCrewCheckInToStorage(duty) {\n //Get all checkIns exept current flight from storage\n var storedCheckIns = getCrewCheckInFromStorage();\n var storedCheckInsFiltered = storedCheckIns.filter(function (f) {\n return f.FlightId != duty.FlightInfo.FlightId;\n }); //Get checkIns from duty and add new crew checkIns to list\n\n if (duty && duty.FlightInfo && duty.FlightInfo.crew) {\n duty.FlightInfo.crew.forEach(function (item) {\n storedCheckInsFiltered.push({\n FlightId: duty.FlightInfo.FlightId,\n CrewId: item.id,\n CheckIn: item.CheckIn,\n WillBeThereAt: item.WillBeThereAt\n });\n }); //save checkIns\n\n setCrewCheckInToStorage(storedCheckInsFiltered);\n }\n }\n /**\r\n * Get Crew CheckIns for specified flight\r\n * @memberof CrewCallFactory\r\n * @param {number} flightId\r\n * @returns {Array} CrewFlightCrewCheckIns \r\n */\n\n\n function getFlightCrewCheckInFromStorage(flightId) {\n var storedCheckIns = getCrewCheckInFromStorage();\n return storedCheckIns.filter(function (x) {\n return x.FlightId == flightId;\n });\n }\n /**\r\n * Clean ls from old flights crew check-ins\r\n * @param {array} flights Synced flights\r\n */\n\n\n function cleanOldData(responseFlightIds) {\n var storedCheckIns = getCrewCheckInFromStorage(); //Filter out crew check-ins of old flights\n\n var previousCheckIns = storedCheckIns.filter(function (x) {\n return responseFlightIds.includes(x.FlightId);\n });\n setCrewCheckInToStorage(previousCheckIns);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('crewInfo', crewInfo);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name crewInfo\r\n * @restrict E\r\n * @description\r\n * Crew Table with a double row per crew member\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function crewInfo($uibModal, UserFactory, PaxInfoFactory) {\n function link(scope, element, attrs) {\n scope.user = UserFactory.getUser();\n scope.openPhoneConfirmation = openPhoneConfirmation;\n scope.showInfoRow = showInfoRow;\n scope.showArrivalFormat = showArrivalFormat;\n scope.hiddenButtonHistory = scope.aircraftroute;\n\n if (scope.type == \"flight\") {\n scope.crewMembers = scope.crew.filter(function (x) {\n return (x.position == 'CP' || x.position == \"FO\") && !x.isDHC;\n }).sort(function (a, b) {\n var positionOrder = ['CP', 'FO'];\n return positionOrder.indexOf(a.position) - positionOrder.indexOf(b.position);\n });\n } else if (scope.type == \"cabin\") {\n scope.crewMembers = scope.crew.filter(function (x) {\n return (x.position == 'SA' || x.position == \"FA\") && !x.isDHC;\n });\n } else {\n scope.crewMembers = scope.crew.filter(function (x) {\n return x.isDHC;\n });\n\n if (scope.crewMembers.length > 0 && !scope.hiddenButtonHistory) {\n PaxInfoFactory.getPaxInfoList(scope.selectedflightid, function (passengerList) {\n if (passengerList) {\n scope.crewMembers.forEach(function (crewMember) {\n var matchedPassenger = passengerList.filter(function (x) {\n return x.IsDHC && x.Fullname.toUpperCase().includes(crewMember.name.toUpperCase());\n });\n\n if (matchedPassenger && matchedPassenger.length > 0) {\n crewMember.seatNo = matchedPassenger[0].SeatNo;\n }\n });\n }\n });\n }\n }\n\n function openPhoneConfirmation(_crew) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/CrewInfo/dlgConfirmCrewCall.html',\n controller: 'CrewCallCtrl',\n size: 'md',\n resolve: {\n crew: function crew() {\n return _crew;\n },\n flightId: function flightId() {\n return scope.selectedflightid;\n },\n groundDutyId: function groundDutyId() {\n return null;\n }\n }\n });\n modalInstance.result.then(function (confirm) {});\n }\n\n function showInfoRow(item) {\n var differentUser = scope.user.aimsId != item.aimsId;\n var phoneAvailable = item.PhoneNumber && item.PhoneNumber != '';\n var previousDutyAvailable = item.PreviousDuty && item.PreviousDuty.isDifferent;\n var phonesAvailable = scope.crew.filter(function (x) {\n return x.PhoneNumber && x.PhoneNumber != '';\n }).length > 0;\n var checkInStatusAvailable = scope.crew.filter(function (x) {\n return x.CheckIn || x.WillBeThereAt;\n }).length > 0;\n var needsAdditionalFeedback = item.needsAdditionalFeedback;\n return differentUser && (phoneAvailable || previousDutyAvailable || phonesAvailable || checkInStatusAvailable || needsAdditionalFeedback);\n }\n\n function showArrivalFormat(previousDuty) {\n var formatedArrival = '';\n var dateFormat = 'HH:mm';\n\n if (previousDuty.showArrivalDate) {\n dateFormat = 'dd/MM HH:mm';\n }\n\n if (previousDuty.ATA) {\n formatedArrival = '- A ' + moment(previousDuty.ATA).format(dateFormat);\n } else if (previousDuty.ETA) {\n formatedArrival = '- E ' + moment(previousDuty.ETA).format(dateFormat);\n } else {\n formatedArrival = '- S ' + moment(previousDuty.STA).format(dateFormat);\n }\n\n return formatedArrival;\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/CrewInfo/crewInfo.tpl.html',\n scope: {\n crew: \"=\",\n type: \"=\",\n selectedflightid: \"=\",\n aircraftroute: \"=\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('crewPreviousInfo', crewPreviousInfo);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name crewPreviousInfo\r\n * @restrict E\r\n * @description\r\n * Crew Table with a double row per crew member showing previous duty info\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function crewPreviousInfo($uibModal, UserFactory) {\n function link(scope, element, attrs) {\n scope.user = UserFactory.getUser();\n scope.filterByPreviousDuty = filterByPreviousDuty;\n\n if (scope.type == \"flight\") {\n scope.crewMembers = scope.crew.filter(function (x) {\n return (x.position == 'CP' || x.position == \"FO\") && !x.isDHC;\n });\n } else if (scope.type == \"cabin\") {\n scope.crewMembers = scope.crew.filter(function (x) {\n return (x.position == 'SA' || x.position == \"FA\") && !x.isDHC;\n });\n } else {\n scope.crewMembers = scope.crew.filter(function (x) {\n return x.isDHC;\n });\n }\n\n function filterByPreviousDuty() {\n return function (crew) {\n return crew.PreviousDuty && crew.PreviousDuty.isDifferent;\n };\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/CrewInfo/crewPreviousInfo.tpl.html',\n scope: {\n crew: \"=\",\n type: \"=\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('LogCallFactory', LogCallFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name LogCallFactory\r\n * @ngInject\r\n */\n\n function LogCallFactory(GenericService, $http, apiUrl) {\n function LogCall() {\n this.Requester = null;\n this.Requestee = null;\n this.FlightId = null;\n this.GroundDutyId = null;\n this.Date = null;\n }\n\n var objType = 'logCall';\n var objCallback = LogCall;\n var service = {\n getLogCallsFromStorage: getLogCallsFromStorage,\n cleanLogsFromStorage: cleanLogsFromStorage,\n saveLogCall: saveLogCall\n };\n /**\r\n * Get Offline Logged Calls.\r\n * @memberof LogCallFactory\r\n */\n\n function getLogCallsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Clean local storage\r\n * @memberof CrewCallFactory\r\n */\n\n\n function cleanLogsFromStorage() {\n GenericService.removeAll(objType, objCallback);\n }\n /**\r\n * Save an offline call request\r\n * @memberof CrewCallFactory\r\n * @param {object} logData \r\n */\n\n\n function saveLogCall(logData) {\n GenericService.add(logData, objType, objCallback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('PreviousDutyFactory', PreviousDutyFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PreviousDutyFactory\r\n * @ngInject\r\n */\n\n function PreviousDutyFactory(GenericService, $http, apiUrl) {\n function PreviousDuty() {\n this.FlightId = null;\n this.CrewId = null;\n this.PreviousDuty = null;\n }\n\n var objType = 'previousDuty';\n var objCallback = PreviousDuty;\n var service = {\n getPreviousDutiesFromStorage: getPreviousDutiesFromStorage,\n setPreviousDutiesToStorage: setPreviousDutiesToStorage,\n getPreviousDutyFromStorage: getPreviousDutyFromStorage,\n getFlightPreviousDutiesFromStorage: getFlightPreviousDutiesFromStorage,\n savePreviousDuty: savePreviousDuty,\n cleanOldData: cleanOldData,\n cleanFlightPreviousDuties: cleanFlightPreviousDuties,\n saveFlightPreviousDuties: saveFlightPreviousDuties\n };\n /**\r\n * Get Crew Phone Numbers.\r\n * @memberof PreviousDutyFactory\r\n * @returns {Array} PreviousDuties \r\n */\n\n function getPreviousDutiesFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Get Crew Phone Numbers for specified flight\r\n * @memberof PreviousDutyFactory\r\n * @param {number} flightId\r\n * @returns {Array} PreviousDuties \r\n */\n\n\n function getFlightPreviousDutiesFromStorage(flightId) {\n var previousDuties = GenericService.list(objType, objCallback);\n return previousDuties.filter(function (x) {\n return x.FlightId == flightId;\n });\n }\n /**\r\n * Save Crew Phone Numbers to storage\r\n * @memberof PreviousDutyFactory\r\n * @param {Array} PreviousDuties\r\n */\n\n\n function setPreviousDutiesToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Get Previous Duty from storage \r\n * @memberof PreviousDutyFactory\r\n * @param {number} crewId\r\n * @param {number} flightId\r\n * @return {object} previous duty info\r\n */\n\n\n function getPreviousDutyFromStorage(crewId, flightId) {\n var previousDuties = getPreviousDutiesFromStorage();\n return previousDuties.find(function (x) {\n return x.FlightId == flightId && x.CrewId == crewId;\n });\n }\n /**\r\n * Save a fetched previous duty\r\n * @memberof PreviousDutyFactory\r\n * @param {object} previousDuty \r\n */\n\n\n function savePreviousDuty(previousDuty) {\n GenericService.add(previousDuty, objType, objCallback);\n }\n /**\r\n * Clean ls from old flight previous duties\r\n * @param {array} flights Synced flights\r\n */\n\n\n function cleanOldData(responseFlightIds) {\n var previousDuties = getPreviousDutiesFromStorage(); //Filter out previous duties of old flights\n\n previousDuties = previousDuties.filter(function (x) {\n return responseFlightIds.includes(x.FlightId);\n });\n setPreviousDutiesToStorage(previousDuties);\n }\n /**\r\n * Clean all stored previous duties for selected flight\r\n * @param {number} flightId \r\n */\n\n\n function cleanFlightPreviousDuties(flightId) {\n var previousDuties = getPreviousDutiesFromStorage();\n previousDuties = previousDuties.filter(function (x) {\n return x.FlightId != flightId;\n });\n setPreviousDutiesToStorage(previousDuties);\n }\n /**\r\n * Save previous duty info for each flight crew member that has one \r\n * @param {number} flightId \r\n * @param {array} crew \r\n */\n\n\n function saveFlightPreviousDuties(flightId, crew) {\n crew.forEach(function (user) {\n if (user.PreviousDuty) {\n var previousDuty = {\n FlightId: flightId,\n CrewId: user.id,\n PreviousDuty: user.PreviousDuty\n };\n savePreviousDuty(previousDuty);\n }\n });\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('CrewContactsModalCtrl', CrewContactsModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CrewContactsModalCtrl\r\n * @description \r\n * Shows crew detais with contacts \r\n * @ngInject\r\n */\n\n function CrewContactsModalCtrl($scope, $timeout, $uibModalInstance, crewInfo, selectedflightid, selectedFlightNo) {\n $scope.crew = crewInfo;\n $scope.selectedflightid = selectedflightid;\n $scope.closeCrewPanel = closeCrewPanel;\n $scope.selectedFlightNo = selectedFlightNo;\n /**\r\n * Close the modal \r\n * @memberof BucketModalCtrl\r\n */\n\n function closeCrewPanel() {\n $uibModalInstance.close();\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CrewHotelFactory', CrewHotelFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewHotelFactory\r\n * @description \r\n * Get hotels\r\n * @ngInject\r\n */\n\n function CrewHotelFactory(GenericService, $http, apiUrl) {\n var objType = 'crewHotel';\n var objCallback = CrewHotel;\n var service = {\n getCrewHotelsFromStorage: getCrewHotelsFromStorage,\n setCrewHotelsToStorage: setCrewHotelsToStorage,\n getCrewHotelFromStorage: getCrewHotelFromStorage\n };\n /**\r\n * Initialize the CrewHotel\r\n * @memberof CrewHotelFactory\r\n */\n\n function CrewHotel() {\n this.AimsId = null;\n this.CrewName = null;\n this.DutyDate = null;\n this.Base = null;\n this.Airport = null;\n this.HotelNo = null;\n this.HotelName = null;\n this.GroundTime = null;\n }\n /**\r\n * Get Crew Hotels\r\n * @memberof CrewHotelFactory\r\n * @returns {Array} CrewHotels \r\n */\n\n\n function getCrewHotelsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save Crew Hotels to storage\r\n * @memberof GroundDutyFactory\r\n * @param {Array} objList A list of Crew Hotels\r\n */\n\n\n function setCrewHotelsToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Get a specific Hotel\r\n * @memberof CrewHotelFactory\r\n * @returns {object} CrewHotel\r\n */\n\n\n function getCrewHotelFromStorage(dutydate) {\n var crewHotels = getCrewHotelsFromStorage();\n if (crewHotels == null) return [];\n var arrayLength = crewHotels.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (crewHotels[i].Dutydate == dutydate) {\n return crewHotels[i];\n }\n }\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CrewMealFactory', CrewMealFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewMealFactory\r\n * @description \r\n * Get and Update Crew Meals \r\n * @ngInject\r\n */\n\n function CrewMealFactory(GenericService, $http, apiUrl) {\n var objType = 'crewMeal';\n var objCallback = CrewMeal;\n var objCallbackRatings = RatingObj;\n var ratingSubmitResponseObj = {\n success: false,\n message: ''\n };\n var service = {\n getCrewMealsFromStorage: getCrewMealsFromStorage,\n setCrewMealsToStorage: setCrewMealsToStorage,\n getCrewMealFromStorage: getCrewMealFromStorage,\n sendCrewMealsRatingReport: sendCrewMealsRatingReport,\n hasRating: hasRating,\n getCrewMealsDidNotEatReasons: getCrewMealsDidNotEatReasons\n };\n /**\r\n * Initialize the CrewMeal\r\n * @memberof CrewMealFactory\r\n */\n\n function CrewMeal() {\n this.CateringMealId = null;\n this.Title = null;\n this.Description = null;\n }\n\n function RatingObj() {\n this.CrewMealId = null, this.TimeStamp = null;\n }\n /**\r\n * Get Crew Meals\r\n * @memberof CrewMealFactory\r\n * @returns {Array} CrewMeals \r\n */\n\n\n function getCrewMealsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save Crew Meals to storage\r\n * @memberof GroundDutyFactory\r\n * @param {Array} objList A list of Crew Meals\r\n */\n\n\n function setCrewMealsToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Get a specific Crew Meal\r\n * @memberof CrewMealFactory\r\n * @returns {object} CrewMeal\r\n */\n\n\n function getCrewMealFromStorage(cateringMealId) {\n var crewMeals = getCrewMealsFromStorage();\n if (crewMeals == null) return [];\n var arrayLength = crewMeals.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (crewMeals[i].CateringMealId == cateringMealId) {\n return crewMeals[i];\n }\n }\n }\n /**\r\n * Checks if the specified crew meal has rating\r\n * @memberof CrewMealFactory\r\n * @returns {boolean} response\r\n */\n\n\n function hasRating(crewMealId) {\n var res = GenericService.list(\"CrewMealRatings\", objCallbackRatings);\n return res.some(function (e) {\n return e.CrewMealId === crewMealId.toString();\n });\n }\n /**\r\n * Sends the crew meals rating report\r\n * @memberof CrewMealFactory\r\n * @returns {ratingSubmitResponseObj} ratingSubmitResponseObj\r\n */\n\n\n function sendCrewMealsRatingReport(ratingForm) {\n var objectToAdd = {\n CrewMealId: ratingForm.CrewMealId,\n TimeStamp: new Date()\n };\n return $http.post(apiUrl + '/CrewMealsRating/SaveReport', ratingForm, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return saveReportSuccessCallBack(res, objectToAdd);\n })[\"catch\"](function (res) {\n return saveReportFailedCallBack(res);\n });\n }\n /**\r\n * The callback function if the save report succeed\r\n * @returns {ratingSubmitResponseObj} ratingSubmitResponseObj\r\n */\n\n\n function saveReportSuccessCallBack(res, objectToAdd) {\n ratingSubmitResponseObj.success = res.data.success;\n\n if (res.data.success) {\n GenericService.add(objectToAdd, \"CrewMealRatings\", objCallbackRatings);\n ratingSubmitResponseObj.message = \"Thank you for your feedback\";\n } else {\n ratingSubmitResponseObj.message = res.data.errorMessage;\n }\n\n return ratingSubmitResponseObj;\n }\n /**\r\n * Gets the choices for the dropdown if a crew member did not eat their meal\r\n * @returns {ratingSubmitResponseObj} ratingSubmitResponseObj\r\n */\n\n\n function getCrewMealsDidNotEatReasons() {\n return $http.get(apiUrl + '/CrewMealsRating/GetCrewMealsDidNotEatReasons', {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return res.data;\n });\n }\n /**\r\n * The callback function if the save report fail\r\n * @returns {ratingSubmitResponseObj} ratingSubmitResponseObj\r\n */\n\n\n function saveReportFailedCallBack(res) {\n ratingSubmitResponseObj.success = false;\n ratingSubmitResponseObj.message = \"Something went wrong!\";\n return ratingSubmitResponseObj;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('CrewRouteCtrl', CrewRouteCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CrewRouteCtrl\r\n * @description \r\n * Shows the crew route information\r\n * @ngInject\r\n */\n\n function CrewRouteCtrl($scope, $filter, $route, $location, $routeParams, $uibModal, FlightFactory, SyncLogFactory, GroundDutyFactory, CrewRouteFactory) {\n var _dutyNo = $routeParams.dutyNo;\n var _dutyDay = $routeParams.dutyDay;\n $scope.crewRouteDuty = CrewRouteFactory.getCrewRouteFromStorage(_dutyNo, _dutyDay);\n var groundDuties = GroundDutyFactory.getGroundDutiesByDutyNo(_dutyNo, _dutyDay);\n\n if (groundDuties.length > 0) {\n //there are ground duties in this crew route\n angular.forEach(groundDuties, function (groundDuty) {\n groundDuty.DutyType = \"Ground\";\n groundDuty.Start = groundDuty.DutyBegin;\n });\n }\n\n var flights = FlightFactory.getFlightsByDutyNo(_dutyNo, _dutyDay);\n\n if (flights.length > 0) {\n //there are flights in this crew route\n angular.forEach(flights, function (flight) {\n flight.DutyType = \"Flight\";\n flight.Start = flight.ScheduledDeparture;\n });\n }\n\n var crewRoute = groundDuties.concat(flights);\n crewRoute = $filter('orderBy')(crewRoute, 'Start', false);\n $scope.crewRoute = crewRoute;\n $scope.currentDutyDay = null;\n $scope.differentDay = differentDay;\n $scope.currentPage = 1;\n $scope.previous = previous;\n $scope.next = next;\n $scope.openRefresh = openRefresh;\n $scope.dutyNo = _dutyNo;\n $scope.dutyDay = _dutyDay;\n $scope.firstFlightId = getFirstFlightId();\n /**\r\n * Get the flightId from the first leg of the route\r\n */\n\n function getFirstFlightId() {\n var flightId = null;\n\n if (flights.length > 0) {\n flightId = flights[0].FlightId;\n }\n\n return flightId;\n }\n /**\r\n * Checks if two dates have the same day\r\n * @param {string} day1 \r\n * @param {string} day2 \r\n */\n\n\n function differentDay(day1, day2) {\n day1 = new Date(day1).trimTime().getDay();\n day2 = new Date(day2).trimTime().getDay();\n return day1 == day2 ? false : true;\n }\n /**\r\n * Moves pager to previous page\r\n */\n\n\n function previous() {\n if ($scope.currentPage != 1) $scope.currentPage--;\n }\n /**\r\n * Moves pager to next page\r\n */\n\n\n function next() {\n if ($scope.currentPage != crewRoute.length) $scope.currentPage++;\n }\n /**\r\n * Opens refresh modal\r\n */\n\n\n function openRefresh() {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/CrewRoute/dlgCrewRouteRefresh.html',\n controller: 'CrewRouteRefreshModalCtrl',\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n crewroute: function crewroute() {\n return $scope.crewRoute;\n },\n crewRouteDuty: function crewRouteDuty() {\n return $scope.crewRouteDuty;\n },\n dutyNo: function dutyNo() {\n return Number(_dutyNo);\n },\n dutyDay: function dutyDay() {\n return Number(_dutyDay);\n },\n forCurrentDay: function forCurrentDay() {\n return null;\n }\n }\n });\n modalInstance.result.then(function (transferData) {\n if (transferData.sync) {\n SyncLogFactory.forceSync();\n $location.path(\"/\"); //crew route has significantly changed\n } else if (transferData.refresh) {\n $route.reload(); //crew route was updated\n }\n });\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CrewRouteFactory', CrewRouteFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewRouteFactory\r\n * @description \r\n * Get and Update Crew Routes \r\n * @ngInject\r\n */\n\n function CrewRouteFactory(GenericService, FlightFactory, GroundDutyFactory, $filter, AircaftPositionsFactory, CrewMealFactory, FlightDelaysFactory) {\n var objType = 'crewRoute';\n var objCallback = CrewRoute;\n var service = {\n getCrewRoutesFromStorage: getCrewRoutesFromStorage,\n setCrewRoutesToStorage: setCrewRoutesToStorage,\n setCourseCompleted: setCourseCompleted,\n setCoursePending: setCoursePending,\n updateCrewMealsInRoute: updateCrewMealsInRoute,\n updateRouteLastRefreshDate: updateRouteLastRefreshDate,\n getCrewRouteFromStorage: getCrewRouteFromStorage,\n getCrewRouteDuties: getCrewRouteDuties,\n getCrewRouteInfoPanel: getCrewRouteInfoPanel,\n getCrewRouteFlights: getCrewRouteFlights,\n updateCrewRouteDuty: updateCrewRouteDuty,\n addCrewRouteDuty: addCrewRouteDuty,\n getManualFlightTrainingsFromStorage: getManualFlightTrainingsFromStorage,\n removeFlightTraining: removeFlightTraining,\n insertCrewRoutesWithPendingTrainings: insertCrewRoutesWithPendingTrainings\n };\n /**\r\n * Initialize the CrewRoute\r\n * @memberof CrewRouteFactory\r\n */\n\n function CrewRoute() {\n this.DutyDay = null;\n this.DutyNo = null;\n this.Route = null;\n this.DutyBegin = null;\n this.DutyEnd = null;\n this.CrewMeals = []; //new property: get the value from CrewAssessmentFactory\n\n this.AssessmentInfo = null;\n this.LastRefreshed = null;\n }\n /**\r\n * Get Crew Routes\r\n * @memberof CrewRouteFactory\r\n * @returns {Array} CrewRoutes \r\n */\n\n\n function getCrewRoutesFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save Crew Routes to storage\r\n * @memberof GroundDutyFactory\r\n * @param {Array} objList A list of Crew Routes\r\n */\n\n\n function setCrewRoutesToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Get a specific Crew Route\r\n * @memberof CrewRouteFactory\r\n * @returns {object} CrewRoute\r\n */\n\n\n function getCrewRouteFromStorage(dutyNo, dutyDay) {\n var crewRoutes = getCrewRoutesFromStorage();\n if (crewRoutes == null) return [];\n var arrayLength = crewRoutes.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (crewRoutes[i].DutyNo == dutyNo && crewRoutes[i].DutyDay == dutyDay) {\n return crewRoutes[i];\n }\n }\n }\n\n function setCourseCompleted(dutyNo, dutyDay, courseId, date) {\n var crewRoutes = getCrewRoutesFromStorage();\n var crewRoute = crewRoutes.find(function (cr) {\n return cr.DutyNo == dutyNo && cr.DutyDay == dutyDay;\n });\n var flightIds = crewRoute.FlightIds;\n var flights = FlightFactory.getFlightsFromStorage().filter(function (x) {\n return flightIds.includes(x.FlightId);\n });\n var crewRouteCourse = crewRoute.Courses.find(function (x) {\n return x.CourseId == courseId && new moment(x.Date).isSame(date);\n });\n if (crewRouteCourse) crewRouteCourse.Status = \"Completed\";\n flights.forEach(function (flight) {\n var flightCourse = flight.Courses.find(function (x) {\n return x.CourseId == courseId && new moment(x.Date).isSame(date);\n });\n\n if (flightCourse) {\n flightCourse.Status = \"Completed\";\n FlightFactory.updateFlight(flight);\n }\n });\n GenericService.saveAll(crewRoutes, objType, objCallback);\n }\n\n function setCoursePending(dutyNo, dutyDay, courseId, date) {\n var crewRoutes = getCrewRoutesFromStorage();\n var crewRoute = crewRoutes.find(function (cr) {\n return cr.DutyNo == dutyNo && cr.DutyDay == dutyDay;\n });\n var crewRouteCourse = crewRoute.Courses.find(function (x) {\n return x.CourseId == courseId && new moment(x.Date).isSame(date);\n });\n if (crewRouteCourse) crewRouteCourse.Status = \"Pending\";\n GenericService.saveAll(crewRoutes, objType, objCallback);\n }\n\n function getCrewRouteDuties(dutyNo, dutyDay, flightDate) {\n var groundDuties = GroundDutyFactory.getGroundDutiesByDutyNo(dutyNo, dutyDay).filter(function (x) {\n return x.DutyDate == flightDate;\n });\n\n if (groundDuties.length > 0) {\n //there are ground duties in this crew route\n angular.forEach(groundDuties, function (groundDuty) {\n groundDuty.DutyType = \"Ground\";\n groundDuty.Start = groundDuty.DutyBegin; // groundDuty.Date = groundDuty.DutyDate;\n });\n } // var flights = FlightFactory.getFlightsByDutyNo(dutyNo, dutyDay).filter(x => x.DutyDate == flightDate);\n\n\n var flights = getCrewRouteFlights(dutyNo, dutyDay, flightDate);\n\n if (flights.length > 0) {\n //there are flights in this crew route\n angular.forEach(flights, function (flight) {\n flight.DutyType = \"Flight\";\n flight.Start = flight.ScheduledDeparture;\n flight.showNextAcPos = false;\n flight.showPreviousAcPos = false;\n flight.hasChangeAircraft = false;\n flight.isFirst = false;\n flight.isLast = false;\n flight.BTime = \"\";\n flight.Delay = 0;\n flight.ArrDelay = 0;\n flight.crewMeals = \"\";\n flight.aircaftPositions = null;\n flight.flightDelays = null;\n });\n }\n\n flights = $filter('orderBy')(flights, 'Start'); // check if aircraft change exists \n\n flights.forEach(function (flight, index, array) {\n flight.isFirst = index == 0;\n flight.isLast = index + 1 == array.length;\n\n if (flight.isFirst) {\n flight.showPreviousAcPos = true;\n }\n\n if (flight.isLast) {\n flight.showNextAcPos = true;\n }\n\n if (!flight.isFirst && flights[index - 1].AcTailNo != flight.AcTailNo) {\n flight.showPreviousAcPos = true;\n }\n\n if (!flight.isLast && flights[index + 1].AcTailNo != flight.AcTailNo) {\n flight.showNextAcPos = true;\n flight.hasChangeAircraft = true;\n }\n\n var diffMin = Date.DifferenceInMinutes(flight.ScheduledDeparture, flight.ScheduledArrival);\n flight.BTime = Date.MinutesToStringSimple(diffMin);\n flight.Delay = moment(flight.ATD).diff(moment(flight.ScheduledDeparture), 'minutes') || \"\";\n flight.ArrDelay = moment(flight.ATA).diff(moment(flight.ScheduledArrival), 'minutes') || \"\";\n flight.aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId(flight.FlightId);\n\n if (flight.aircaftPositions) {\n // Previous Flight\n flight.aircaftPositions.PreviousFlightDelay = moment(flight.aircaftPositions.PreviousATD).diff(moment(flight.aircaftPositions.PreviousSTD), 'minutes') || \"\";\n flight.aircaftPositions.PreviousFlightArrDelay = moment(flight.aircaftPositions.PreviousATA).diff(moment(flight.aircaftPositions.PreviousSTA), 'minutes') || \"\";\n var diffPreviousFlightMin = Date.DifferenceInMinutes(flight.aircaftPositions.PreviousSTD, flight.aircaftPositions.PreviousSTA);\n flight.aircaftPositions.PreviousFlightBTime = Date.MinutesToStringSimple(diffPreviousFlightMin);\n flight.aircaftPositions.PreviousDelays = FlightDelaysFactory.getFlightDelaysByFlightId(flight.aircaftPositions.PreviousFlightId); // Next Flight\n\n flight.aircaftPositions.NextFlightDelay = moment(flight.aircaftPositions.NextATD).diff(moment(flight.aircaftPositions.NextSTD), 'minutes') || \"\";\n flight.aircaftPositions.NextFlightArrDelay = moment(flight.aircaftPositions.NextATA).diff(moment(flight.aircaftPositions.NextSTA), 'minutes') || \"\";\n var diffNextFlightMin = Date.DifferenceInMinutes(flight.aircaftPositions.NextSTD, flight.aircaftPositions.NextSTA);\n flight.aircaftPositions.NextFlightBTime = Date.MinutesToStringSimple(diffNextFlightMin);\n flight.aircaftPositions.NextDelays = FlightDelaysFactory.getFlightDelaysByFlightId(flight.aircaftPositions.NextFlightId);\n }\n\n flight.flightDelays = FlightDelaysFactory.getFlightDelaysByFlightId(flight.FlightId);\n });\n var crewRouteDuties = groundDuties.concat(flights);\n crewRouteDuties = $filter('orderBy')(crewRouteDuties, 'Start');\n return crewRouteDuties;\n }\n\n function getCrewRouteFlights(dutyNo, dutyDay, flightDate) {\n var crewRoutes = getCrewRoutesFromStorage();\n var crewRoute = crewRoutes.find(function (cr) {\n return cr.DutyNo == dutyNo && cr.DutyDay == dutyDay;\n });\n var flightIds = crewRoute.FlightIds;\n var flights = FlightFactory.getFlightsFromStorage().filter(function (x) {\n return flightIds.includes(x.FlightId) && x.FlightDate == flightDate;\n });\n return flights;\n }\n\n function updateCrewRouteDuty(flightTraining) {\n GenericService.updateFlight(flightTraining, objType, objCallback);\n }\n\n function addCrewRouteDuty(flightTraining) {\n var crewRoutes = getCrewRoutesFromStorage();\n var crewRoute = crewRoutes.find(function (cr) {\n return cr.DutyNo == flightTraining.DutyNo && cr.DutyDay == flightTraining.DutyDay;\n });\n\n if (crewRoute) {\n crewRoute.isManualEntry = true;\n crewRoute.hasPendingCourse = true;\n } else {\n GenericService.add(flightTraining, objType, objCallback);\n }\n }\n\n function removeFlightTraining(dutyNo, dutyDay) {\n var crewRoutes = getCrewRoutesFromStorage();\n var crewRoute = crewRoutes.find(function (cr) {\n return cr.DutyNo == dutyNo && cr.DutyDay == dutyDay;\n });\n crewRoute.isManualEntry = false;\n crewRoute.hasPendingCourse = false;\n GenericService.saveAll(crewRoutes, objType, objCallback);\n }\n /**Get manual flight trainings from storage*/\n\n\n function getManualFlightTrainingsFromStorage() {\n var crewRoutes = getCrewRoutesFromStorage();\n return crewRoutes.filter(function (x) {\n return x.isManualEntry;\n });\n }\n\n function updateCrewMealsInRoute(dutyNo, dutyDay, newCrewMeals, newFlightIds) {\n var crewRoutes = getCrewRoutesFromStorage();\n var crewRoute = crewRoutes.find(function (cr) {\n return cr.DutyNo == dutyNo && cr.DutyDay == dutyDay;\n });\n var crewMealsInRoute = crewRoute.CrewMeals.filter(function (f) {\n return !newFlightIds.includes(f.FlightId);\n });\n crewMealsInRoute = crewMealsInRoute.concat(newCrewMeals);\n crewRoute.CrewMeals = crewMealsInRoute;\n GenericService.saveAll(crewRoutes, objType, objCallback);\n }\n\n function insertCrewRoutesWithPendingTrainings(instructorPendingRoutes) {\n if (instructorPendingRoutes.length > 0) {\n var crewRoutes = getCrewRoutesFromStorage();\n var crewRoutesIdsLS = crewRoutes.map(function (x) {\n return x.DutyNo;\n });\n var routesToInsert = instructorPendingRoutes.filter(function (f) {\n return !crewRoutesIdsLS.includes(f.DutyNo);\n });\n\n if (routesToInsert.length > 0) {\n var updatedCrewRoutesList = crewRoutes.concat(routesToInsert);\n GenericService.saveAll(updatedCrewRoutesList, objType, objCallback);\n }\n }\n }\n /**\r\n * Update last Refresh date for a specific Crew Route\r\n * @memberof CrewRouteFactory\r\n */\n\n\n function updateRouteLastRefreshDate(dutyNo, dutyDay) {\n var crewRoutes = getCrewRoutesFromStorage();\n var crewRoute = crewRoutes.find(function (cr) {\n return cr.DutyNo == dutyNo && cr.DutyDay == dutyDay;\n });\n crewRoute.LastRefreshed = moment().toDate().toUTC();\n GenericService.saveAll(crewRoutes, objType, objCallback);\n }\n /**\r\n * Get Crew Route Info panel information (inside Flight-page)\r\n * @memberof CrewRouteFactory\r\n * @returns {object} flights\r\n */\n\n\n function getCrewRouteInfoPanel(flight) {\n var panelInfo = null;\n var crewRouteInfo = getCrewRouteFromStorage(flight.DutyNo, flight.DutyDay);\n var crewRouteDuties = getCrewRouteDuties(flight.DutyNo, flight.DutyDay, flight.FlightDate);\n var crewRouteFlightDuties = crewRouteDuties.filter(function (x) {\n return x.DutyType === \"Flight\";\n });\n var hasAircraftPositions = crewRouteFlightDuties.length && crewRouteFlightDuties.length > 0 && crewRouteFlightDuties[0].aircaftPositions != null; //update crewRouteDuties with the crewMeals\n\n var crewMealsPerFlightId = [];\n crewRouteInfo.CrewMeals.forEach(function (meals) {\n if (meals.CrewMealsCateringIds) {\n var crewMealsTitles = \"\";\n\n for (var j = 0; j < Object.values(meals.CrewMealsCateringIds).length; j++) {\n if (j != 0) {\n crewMealsTitles += \" & \";\n }\n\n var crewMealDetails = CrewMealFactory.getCrewMealFromStorage(Object.values(meals.CrewMealsCateringIds)[j]);\n crewMealsTitles += crewMealDetails.ShortTitle;\n }\n\n crewMealsPerFlightId.push({\n flightId: meals.FlightId,\n crewMeals: crewMealsTitles\n });\n }\n });\n\n if (crewMealsPerFlightId.length > 0) {\n crewRouteDuties.forEach(function (duty) {\n if (duty.FlightId == crewMealsPerFlightId[0].flightId) {\n duty.crewMeals = crewMealsPerFlightId[0].crewMeals;\n }\n });\n }\n\n var routeNeedRefresh = false;\n\n if (!crewRouteInfo.LastRefreshed) {\n routeNeedRefresh = true;\n }\n\n return panelInfo = {\n crewRouteDuties: crewRouteDuties,\n routeNeedRefresh: routeNeedRefresh,\n hasAircraftPositions: hasAircraftPositions\n };\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('CrewRouteRefreshModalCtrl', CrewRouteRefreshModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CrewRouteRefreshModalCtrl\r\n * @description \r\n * \r\n * @ngInject\r\n */\n\n function CrewRouteRefreshModalCtrl($scope, $filter, $uibModalInstance, crewroute, crewRouteDuty, dutyNo, dutyDay, forCurrentDay, InfoAPIService, FlightSessionFactory, CourseFactory, AirportContactFactory, CrewRouteFactory, LuggageComplianceFactory, GroundServicesFactory, AircraftDifferencesFactory, AirportHotelFactory, TimeLogFactory, CrewCallFactory, PreviousDutyFactory, CampaignFactory, AimsCrewMemosFactory, FlightDelaysFactory, CustomerEventHistoryFactory, FlightServiceEventsFactory) {\n //timer\n var t0 = performance.now();\n var timeLog = \"RefreshFlight: \";\n var tFrom = 0;\n var tTo = 0; // tFrom = performance.now();\n // //do smth\n // tTo = performance.now();\n // timeLog = timeLog + \" | smthTime: \" + (tTo-tFrom); \n\n $scope.isRefreshing = true;\n $scope.refreshResultsVisible = false;\n $scope.error = false;\n $scope.sync = false;\n $scope.collapse = collapse;\n $scope.close = close;\n $scope.crewroute = crewroute;\n $scope.crewRouteDuty = crewRouteDuty;\n $scope.crewRouteGeneral = {\n statuses: [],\n isCollapsed: false\n }; //For refresh Flight page: forCurrentDay is not null\n\n if (forCurrentDay) {\n //Get only the flights from the current day\n var currentDayDuties = crewroute.filter(function (item) {\n return item.DutyType == 'Flight' && item.FlightDate == forCurrentDay || item.DutyType == 'Ground' && item.DutyDate == forCurrentDay;\n });\n crewroute = currentDayDuties;\n $scope.crewroute = currentDayDuties;\n crewRouteDuty.CurrentDutyDate = forCurrentDay;\n\n if (currentDayDuties.some(function (s) {\n return s.DutyType == 'Flight';\n })) {\n $scope.crewRouteGeneral.statuses = [{\n datatype: \"Meals\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Campaigns\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Hotels\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Airport Contacts\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Ground Services\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Aircraft Differences\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Aims Memos\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Flight Service Events\",\n status: \"PENDING\",\n text: \"Pending...\"\n }];\n }\n } //add DataStatus to each duty\n\n\n for (var i = 0; i < crewroute.length; i++) {\n if (crewroute[i].DutyType == 'Flight') {\n crewroute[i].DataStatus = [{\n datatype: \"Flight Status\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Aircraft Movement\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Crew Info\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Crew Contacts\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Pax Info\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Connections\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Luggage Info\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Training Info\",\n status: \"PENDING\",\n text: \"Pending...\"\n }];\n } else if (crewroute[i].DutyType == 'Ground') {\n if (crewroute[i].isTraining) {\n crewroute[i].DataStatus = [{\n datatype: \"Duty Info\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Instructors\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Trainees\",\n status: \"PENDING\",\n text: \"Pending...\"\n }];\n } else {\n crewroute[i].DataStatus = [{\n datatype: \"Duty Info\",\n status: \"PENDING\",\n text: \"Pending...\"\n }];\n }\n }\n } //separate flights and groundDuties \n\n\n var currentFlights = [];\n var currentGroundDuties = [];\n\n for (var i = 0; i < crewroute.length; i++) {\n if (crewroute[i].DutyType == 'Flight') currentFlights.push(crewroute[i]);else if (crewroute[i].DutyType == 'Ground') currentGroundDuties.push(crewroute[i]);\n crewroute[i].isCollapsed = false;\n } //get latest info\n\n\n InfoAPIService.refreshCrewRoute(crewRouteDuty, function (responseData) {\n tTo = performance.now();\n timeLog = timeLog + \" | apiResponseTime: \" + (tTo - t0);\n $scope.isRefreshing = false;\n var response = responseData.data.data;\n var responseStatuses = {\n meals: false,\n airportContacts: false,\n groundServices: false,\n aircraftDifferences: false,\n airportHotels: false,\n campaigns: false,\n crewAimsMemos: false,\n flightServiceEvents: false\n };\n\n if (forCurrentDay) {\n //Update CrewMeals in the current route // only for refresh flight\n if (response.CrewMeals != undefined && response.CrewMeals != null) {\n var responseFlightIds = response.Flights.map(function (x) {\n return x.FlightInfo.FlightId;\n });\n tFrom = performance.now();\n CrewRouteFactory.updateCrewMealsInRoute(dutyNo, dutyDay, response.CrewMeals, responseFlightIds);\n responseStatuses.meals = true;\n tTo = performance.now();\n timeLog = timeLog + \" | updateCrewMealsInRoute: \" + (tTo - tFrom);\n } // Update Airport Contacts\n\n\n if (response.AirportContacts && response.AirportContacts.length > 0) {\n tFrom = performance.now();\n AirportContactFactory.upsertAirportContacts(response.AirportContacts);\n responseStatuses.airportContacts = true;\n tTo = performance.now();\n timeLog = timeLog + \" | upsertAirportContacts: \" + (tTo - tFrom);\n } // Update ground services\n\n\n if (response.GroundServices && response.GroundServices.length > 0) {\n tFrom = performance.now();\n GroundServicesFactory.upsertGroundServices(response.GroundServices);\n responseStatuses.groundServices = true;\n tTo = performance.now();\n timeLog = timeLog + \" | upsertGroundServices: \" + (tTo - tFrom);\n } // Update aircraft differences\n\n\n if (response.AircraftDifferences && response.AircraftDifferences.length > 0) {\n tFrom = performance.now();\n AircraftDifferencesFactory.upsertAircraftDifferences(response.AircraftDifferences);\n responseStatuses.aircraftDifferences = true;\n tTo = performance.now();\n timeLog = timeLog + \" | upsertAircraftDifferences: \" + (tTo - tFrom);\n } // Update airport hotels\n\n\n if (response.AirportHotels && response.AirportHotels.length > 0) {\n tFrom = performance.now();\n AirportHotelFactory.upsertAirportHotels(response.AirportHotels);\n responseStatuses.airportHotels = true;\n tTo = performance.now();\n timeLog = timeLog + \" | upsertAirportHotels: \" + (tTo - tFrom);\n } // Update Aims Crew Memos\n\n\n if (response.CrewAimsMemos && response.CrewAimsMemos.length > 0) {\n tFrom = performance.now();\n AimsCrewMemosFactory.upsertAimsCrewMemos(response.CrewAimsMemos);\n responseStatuses.crewAimsMemos = true;\n tTo = performance.now();\n timeLog = timeLog + \" | upsertAimsCrewMemos: \" + (tTo - tFrom);\n } // Update campaigns\n\n\n if (response.Campaigns && response.Campaigns.FlightsCampaigns.length > 0) {\n tFrom = performance.now();\n CampaignFactory.mergeCampaigns(response.Campaigns);\n responseStatuses.campaigns = true;\n tTo = performance.now();\n timeLog = timeLog + \" | mergeCampaigns: \" + (tTo - tFrom);\n } // Update Flight Delays\n\n\n if (response.FlightDelays && response.FlightDelays.length > 0) {\n tFrom = performance.now();\n FlightDelaysFactory.upsertFlightDelays(response.FlightDelays);\n tTo = performance.now();\n timeLog = timeLog + \" | upsertFlightDelays: \" + (tTo - tFrom);\n } //Get Customer Event History - one stop shop\n\n\n if (response.OneStopShop && response.OneStopShop.CustomerEventHistory && response.OneStopShop.CustomerEventHistory.length > 0) {\n tFrom = performance.now();\n CustomerEventHistoryFactory.refreshPassengerHistory(response.OneStopShop.CustomerEventHistory);\n tTo = performance.now();\n timeLog = timeLog + \" | mergeCampaigns: \" + (tTo - tFrom);\n } //Get flight service events\n\n\n if (response.FlightServiceEvents && response.FlightServiceEvents.length > 0) {\n tFrom = performance.now();\n responseStatuses.flightServiceEvents = true;\n FlightServiceEventsFactory.upsertEvents(response.FlightServiceEvents);\n tTo = performance.now();\n timeLog = timeLog + \" | upsertFlightServiceEvents \" + (tTo - tFrom);\n }\n } //if there are significant changes in crew route user should sync\n\n\n tFrom = performance.now();\n var needsSynchCheck = needsSynch(currentFlights, response.Flights, currentGroundDuties, response.GroundDuties);\n tTo = performance.now();\n timeLog = timeLog + \" | needsSynchCheck: \" + (tTo - tFrom);\n\n if (needsSynchCheck) {\n $scope.sync = true;\n } else {\n //Manage details info and Update local storage\n if (response.Flights.length) {\n //Manage crew route statuses\n tFrom = performance.now();\n InfoAPIService.updateCrewRouteStatusSetter($scope.crewRouteGeneral.statuses, responseStatuses);\n tTo = performance.now();\n timeLog = timeLog + \" | updateCrewRouteStatusSetter: \" + (tTo - tFrom);\n tFrom = performance.now();\n setupFlightInfo(response.Flights);\n tTo = performance.now();\n timeLog = timeLog + \" | setupFlightInfo: \" + (tTo - tFrom);\n tFrom = performance.now();\n updateFlights(response.Flights);\n tTo = performance.now();\n timeLog = timeLog + \" | updateFlights: \" + (tTo - tFrom); //Save training\n\n tFrom = performance.now();\n response.Flights.forEach(function (flight) {\n var trainingCourses = flight.TrainingCourses;\n\n if (trainingCourses && trainingCourses.length && flight.FlightInfo) {\n trainingCourses.forEach(function (trainingCourse) {\n CourseFactory.upsertCourse(trainingCourse, function (course) {\n FlightSessionFactory.applyTraineeInfoToSession(course, course.Id, new moment(flight.FlightInfo.FlightDate).format(\"YYYY-MM-DD\"), dutyNo, dutyDay, function (session) {});\n });\n });\n }\n });\n tTo = performance.now();\n timeLog = timeLog + \" | SaveTraining: \" + (tTo - tFrom);\n }\n\n if (response.GroundDuties.length) {\n tFrom = performance.now();\n setupGroundInfo(response.GroundDuties);\n tTo = performance.now();\n timeLog = timeLog + \" | setupGroundInfo: \" + (tTo - tFrom);\n tFrom = performance.now();\n updateGroundDuties(response.GroundDuties);\n tTo = performance.now();\n timeLog = timeLog + \" | updateGroundDuties: \" + (tTo - tFrom);\n }\n\n $scope.refreshResultsVisible = true;\n tFrom = performance.now();\n CrewRouteFactory.updateRouteLastRefreshDate(dutyNo, dutyDay);\n tTo = performance.now();\n timeLog = timeLog + \" | updateRouteLastRefreshDate: \" + (tTo - tFrom);\n tTo = performance.now();\n timeLog = timeLog + \" | Start-End: \" + (tTo - t0);\n TimeLogFactory.timeLogToStorage(timeLog, response.Timelog);\n }\n })[\"catch\"](function () {\n $scope.error = true;\n $scope.isRefreshing = false;\n });\n /**\r\n * Checks if crew route has significantly changed and needs sync\r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {array} currentFlights Array of current flights\r\n * @param {array} newFlights Array of newly fetched flights\r\n * @param {array} currentGroundDuties Array of current ground duties\r\n * @param {array} newGroundDuties Array of newly fetched ground duties\r\n */\n\n function needsSynch(currentFlights, newFlights, currentGroundDuties, newGroundDuties) {\n var sync = false; //1.Crew Route may not exist any more\n\n if (!newFlights.length && !newGroundDuties.length) {\n sync = true;\n } //2.Duties may have been added/removed \n else if (newFlights.length != currentFlights.length || newGroundDuties.length != currentGroundDuties.length) {\n sync = true; //different size arrays\n } else {\n //same size arrays\n if (currentFlights.length && newFlights.length) {\n //compare current with new flights\n currentFlights = $filter('orderBy')(currentFlights, 'FlightId');\n newFlights = $filter('orderBy')(newFlights, 'FlightInfo.FlightId');\n\n for (var i = 0; i < currentFlights.length; i++) {\n if (newFlights[i].FlightInfo && currentFlights[i].FlightId != newFlights[i].FlightInfo.FlightId) {\n sync = true;\n break;\n }\n }\n }\n\n if (currentGroundDuties.length && newGroundDuties.length) {\n //compare current with new ground duties\n currentGroundDuties = $filter('orderBy')(currentGroundDuties, 'Id');\n newGroundDuties = $filter('orderBy')(newGroundDuties, 'Id');\n\n for (var i = 0; i < currentGroundDuties.length; i++) {\n if (currentGroundDuties[i].Id != newGroundDuties[i].Id) {\n sync = true;\n break;\n }\n }\n }\n }\n\n return sync;\n }\n /**\r\n * Updates Flight in Local Storage\r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {array} newFlights \r\n */\n\n\n function updateFlights(newFlights) {\n for (var i = 0; i < newFlights.length; i++) {\n InfoAPIService.updateFlightLocalStorage(newFlights[i]);\n InfoAPIService.updatePhiloxeniaQuestions(newFlights[i]);\n LuggageComplianceFactory.updateLuggageComplianceStorage(newFlights[i].LuggageCompliance, newFlights[i].FlightId);\n InfoAPIService.updateCrewCheckIn(newFlights[i]); //Update previous Duties & phone calls\n //1. First remove all additional info (phone numbers & previous duties) for this flight\n\n CrewCallFactory.cleanFlightCrewNumbers(newFlights[i].FlightInfo.FlightId);\n PreviousDutyFactory.cleanFlightPreviousDuties(newFlights[i].FlightInfo.FlightId); //2. Then save any fetched info\n\n if (newFlights[i].FlightInfo) {\n var crew = newFlights[i].FlightInfo.crew;\n CrewCallFactory.saveFlightPhoneNumbers(newFlights[i].FlightInfo.FlightId, crew, newFlights[i].FlightInfo.ScheduledArrival, newFlights[i].FlightInfo.ScheduledDeparture);\n PreviousDutyFactory.saveFlightPreviousDuties(newFlights[i].FlightInfo.FlightId, crew);\n }\n }\n }\n /**\r\n * Updates Flight's Data Status\r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {array} newFlights \r\n */\n\n\n function setupFlightInfo(newFlights) {\n newFlights = $filter('orderBy')(newFlights, 'Start', false);\n currentFlights = $filter('orderBy')(currentFlights, 'Start', false);\n\n for (var i = 0; i < newFlights.length; i++) {\n InfoAPIService.updateFlightStatusSetter(newFlights[i], currentFlights[i].DataStatus);\n }\n }\n /**\r\n * Updates Ground Duty's Data Status\r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {array} newGroundDuties \r\n */\n\n\n function setupGroundInfo(newGroundDuties) {\n newGroundDuties = $filter('orderBy')(newGroundDuties, 'Start', false);\n currentGroundDuties = $filter('orderBy')(currentGroundDuties, 'Start', false);\n\n for (var i = 0; i < newGroundDuties.length; i++) {\n InfoAPIService.updateGroundStatusSetter(newGroundDuties[i], currentGroundDuties[i].DataStatus);\n }\n }\n /**\r\n * Updates Ground Duty in Local Storage\r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {array} newFlights \r\n */\n\n\n function updateGroundDuties(newGroundDuties) {\n for (var i = 0; i < newGroundDuties.length; i++) {\n InfoAPIService.updateGroundDutyLocalStorage(newGroundDuties[i]);\n }\n }\n /**\r\n * Shows Details \r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {object} duty \r\n */\n\n\n function collapse(duty) {\n if (!$scope.isRefreshing && $scope.refreshResultsVisible) duty.isCollapsed = !duty.isCollapsed;\n }\n /**\r\n * Closes the modal\r\n * @memberof CrewRouteRefreshModalCtrl\r\n */\n\n\n function close() {\n $uibModalInstance.close({\n sync: $scope.sync,\n refresh: $scope.refreshResultsVisible\n });\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('CustomerModalCtrl', CustomerModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CustomerCtrl\r\n * @description \r\n * Report a bug of the application\r\n * @ngInject\r\n */\n\n function CustomerModalCtrl($scope, $uibModalInstance, $timeout, InfoAPIService, customerIncident) {\n $scope.successful = false;\n $scope.error = false;\n var q = InfoAPIService.sendCustomerIncident(customerIncident.flightDescription, customerIncident.question, customerIncident.description, customerIncident.image);\n q.then(function (responseData) {\n if (responseData.data.data) {\n $scope.successful = true;\n } else {\n $scope.error = true;\n }\n\n $timeout(function () {\n $uibModalInstance.close();\n }, 3000);\n }, function () {\n $scope.error = true;\n $timeout(function () {\n $uibModalInstance.close();\n }, 3000);\n });\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('aircraftDifferences', aircraftDifferences);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name aircraftDifferences\r\n * @restrict E\r\n * @description\r\n * Implementation of aircraft differences\r\n *\r\n * Display the differences of Aircrafts\r\n * @attr {String} registration The registration of the aircraft.\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function aircraftDifferences(AircraftDifferencesFactory) {\n function link(scope, element, attributes) {\n var AircraftDifferencesObj = AircraftDifferencesFactory.getAircraftDifferenceFromStorageByRegistration(attributes.registration);\n scope.AircraftDifferences = AircraftDifferencesObj != null && AircraftDifferencesObj.AircraftDifferences != null ? AircraftDifferencesObj.AircraftDifferences : [];\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/directives/aircraftDifferences.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('autorefresh', autorefresh);\n\n function autorefresh($interval, $timeout, PushNotifier, InfoAPIService, FlightFactory, PaxInfoFactory, AircaftPositionsFactory, CrewCallFactory, PreviousDutyFactory, CrewRouteFactory) {\n function link($scope, element, attrs) {\n //var flight = $scope.flight;\n //$scope.flight from parent scope\n //Auto refresh functionality start\n var browserNotificationsEnabled = false;\n var autoUpdateInterval = null;\n var autoUpdateIntervalTimeOffset = null;\n $scope.showAlternativeNotifications = false;\n $scope.showAutoUpdatePanel = false; //Check if push notification are enabled\n\n PushNotifier.CheckForPermissionsAndSupport().then(function (res) {\n browserNotificationsEnabled = res;\n });\n var ScheduledDepartureTimeStamp = 0;\n\n if ($scope.flight) {\n ScheduledDepartureTimeStamp = moment.utc($scope.flight.ScheduledDeparture).valueOf();\n }\n\n var now = moment().valueOf();\n $scope.showAutoUpdatePanel = ScheduledDepartureTimeStamp - 70 * 60000 <= now && ScheduledDepartureTimeStamp + 30 * 60000 >= now && $scope.flight.DepartureEU;\n $scope.radioModel = false;\n $scope.$watch('radioModel', function (value) {\n if (value == true) autoflightInfoInterval();\n\n if (value == false) {\n $interval.cancel(autoUpdateInterval);\n autoUpdateInterval = null;\n }\n });\n\n function autoflightInfoInterval() {\n var intervalTime = timerDelayGenerator($scope.flight.ScheduledDeparture);\n var currentInfo = null;\n PushNotifier.formatInfoToCompare($scope.flight.FlightId).then(function (data) {\n currentInfo = data;\n\n if (intervalTime > 0) {\n InfoAPIService.getPax($scope.flight.FlightId).then(function (responseData) {\n $scope.flight = FlightFactory.getFlightFromTotalFlights($scope.flight.FlightId); //UPDATE CREW INFO\n //1. First remove all additional info (phone numbers & previous duties) for this flight\n\n CrewCallFactory.cleanFlightCrewNumbers($scope.flight.FlightId);\n PreviousDutyFactory.cleanFlightPreviousDuties($scope.flight.FlightId); //2. Then save any fetched info\n\n if (responseData.data.data.FlightInfo) {\n var crew = responseData.data.data.FlightInfo.crew;\n CrewCallFactory.saveFlightPhoneNumbers($scope.flight.FlightId, crew, $scope.flight.ScheduledArrival, $scope.flight.ScheduledDeparture);\n PreviousDutyFactory.saveFlightPreviousDuties($scope.flight.FlightId, crew);\n }\n\n PaxInfoFactory.getPaxInfoFromStorage($scope.flight.FlightId, function (paxInfo) {\n $scope.paxInfo = paxInfo;\n\n if (paxInfo) {\n $scope.cStat = paxInfo.PaxTotalC / paxInfo.ConfigurationC * 100;\n $scope.yStat = paxInfo.PaxTotalY / paxInfo.ConfigurationY * 100;\n $scope.mealsChart = $scope.generateMealChart(paxInfo);\n var listSentTimestamp = new Date(paxInfo.LastRun).getTime();\n var DepartureTimestamp = new Date($scope.flight.ScheduledDeparture).getTime(); //20 minutes before takeoff\n\n if (DepartureTimestamp - listSentTimestamp <= 1200000) {\n $scope.IsProvisional = false;\n }\n }\n }); //Update scopes for the CrewRoutePanel in Flight-page\n\n $scope.crewRouteInfoPanel = CrewRouteFactory.getCrewRouteInfoPanel($scope.flight);\n $scope.aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId($scope.flight.FlightId);\n $scope.flightETA = $scope.flight.ETA ? moment($scope.flight.ETA).valueOf() : new Date($scope.flight.ScheduledArrival).getTime();\n var updatedInfo = null;\n PushNotifier.formatInfoToCompare($scope.flight.FlightId).then(function (data) {\n updatedInfo = data;\n var changes = PushNotifier.compareAndExtractChanges(currentInfo, updatedInfo);\n var message = PushNotifier.MessageGenerator(changes);\n\n if (changes && changes.length > 0) {\n if (browserNotificationsEnabled) {\n try {\n PushNotifier.Generate('Changes', message);\n } catch (e) {\n $scope.changes = changes;\n $scope.showAlternativeNotifications = true;\n }\n } else {\n $scope.changes = changes;\n $scope.showAlternativeNotifications = true;\n }\n }\n });\n }, function (responseData) {\n if (browserNotificationsEnabled && window.navigator.onLine) {\n try {\n PushNotifier.Generate('Changes', 'Update failed');\n } catch (ex) {//TODO: add related messagge KVEN,EPAP\n }\n }\n });\n\n if (intervalTime != autoUpdateIntervalTimeOffset) {\n autoUpdateIntervalTimeOffset = intervalTime;\n $interval.cancel(autoUpdateInterval);\n autoUpdateInterval = $interval(autoflightInfoInterval, autoUpdateIntervalTimeOffset);\n }\n } else {\n $interval.cancel(autoUpdateInterval);\n $scope.showAutoUpdatePanel = false;\n }\n });\n }\n\n function timerDelayGenerator(departureTime) {\n var intervalTime = -1;\n var depTimestamp = moment.utc(departureTime).valueOf();\n var nowTimeStamp = moment().valueOf();\n var minutes = 60000;\n\n if (depTimestamp - 70 * minutes <= nowTimeStamp && depTimestamp + 30 * minutes >= nowTimeStamp) {\n var absoluteMinuteDiff = Math.abs(depTimestamp - nowTimeStamp);\n\n if (absoluteMinuteDiff <= 15 * minutes) {\n intervalTime = 1 * minutes;\n } else {\n intervalTime = 3 * minutes;\n }\n }\n\n return intervalTime;\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: 'views/directives/autofresh.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('basicFooter', basicFooter);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name basicFooter\r\n * @restrict E\r\n * @description\r\n * Implementation of basicFooter (appears in groundDuty-info view)\r\n *\r\n * Initialize a basic Footer Template and its Navigation Functionality\r\n * Used in groundDuty and crewRoute view\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function basicFooter($location, SettingsMain, UserFactory, DataCleanerFactory) {\n /**\r\n * Initialize basicFooter and events\r\n * @memberof basicFooter\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attrs attribute of this element\r\n */\n function link(scope, element, attrs) {\n if (scope.groundDuty || scope.crewRoute) {\n /**\r\n * Open a modal from which u can Logout from the application\r\n * @memberof groundFooter \r\n */\n var logout = function logout() {\n var isSecure = UserFactory.isSecure();\n bootbox.dialog({\n message: (isSecure ? \"Due to the fact that you are working over a public computer, all stored data will be deleted on logout!

\" : \"You will be able to login again into the same account, even if there is no internet access.

\") + \"Please confirm that you wish to log out.\",\n title: \"User Logout\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n logout: {\n label: \"Logout\",\n className: \"btn-warning\",\n callback: function callback() {\n UserFactory.clearActiveUser();\n if (isSecure) DataCleanerFactory.deleteAllData();\n UserFactory.azSignOut();\n location.reload(true); // need to reload, in order for the\n // browser to check the cache.manifest\n // and discover any changes\n }\n }\n }\n });\n };\n /**\r\n * Navigate to Calendar View\r\n * @memberof groundFooter \r\n */\n\n\n var gotoCalendar = function gotoCalendar() {\n // handleIfReport(state, flightId, report);\n SettingsMain.setEditingPage(null); // go to dashboard\n\n $location.path(\"/\");\n };\n /**\r\n * Navigate to Bucket Calendar View\r\n * @memberof groundFooter \r\n */\n\n\n var gotoBucketCalendar = function gotoBucketCalendar() {\n SettingsMain.setEditingPage(null);\n $location.path('/bucket');\n };\n /**\r\n * Navigate to FAQs View\r\n * @memberof groundFooter \r\n */\n\n\n var gotoFAQs = function gotoFAQs() {\n SettingsMain.setEditingPage(null);\n $location.path('/faqs');\n };\n /**\r\n * Navigate to Roster Requests View\r\n * @memberof mainFooter \r\n */\n\n\n var gotoRequests = function gotoRequests() {\n SettingsMain.setEditingPage(null);\n $location.path(\"/rosterRequests\");\n };\n /**\r\n * Navigate to Messages View\r\n * @memberof groundFooter \r\n */\n\n\n var gotoMessageLibrary = function gotoMessageLibrary() {\n $location.path('/messages');\n };\n /**\r\n * Navigate to Meal Library View\r\n * @memberof groundFooter \r\n */\n\n\n var gotoMealLibrary = function gotoMealLibrary() {\n $location.path('/mealLibrary');\n };\n\n var state = scope.state;\n var user = UserFactory.getUser();\n var delay = 60000;\n scope.gotoMessageLibrary = gotoMessageLibrary;\n scope.gotoFAQs = gotoFAQs;\n scope.gotoRequests = gotoRequests;\n scope.gotoBucketCalendar = gotoBucketCalendar;\n scope.gotoCalendar = gotoCalendar;\n scope.gotoMealLibrary = gotoMealLibrary;\n scope.logout = logout;\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: \"views/Main/basic-footer.tpl.html\",\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('campaigns', campaigns);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name campaigns\r\n * @restrict E\r\n * @description\r\n * Implementation of issues\r\n *\r\n * Initialize the campaigns template\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function campaigns($uibModal, CampaignFactory) {\n var _ref;\n\n function link(scope) {\n scope.currentTreatment = 0;\n scope.previousTreatment = previousTreatment;\n scope.nextTreatment = nextTreatment;\n scope.openAssignment = openAssignment;\n scope.FlightCampaigns = {}; //Keeps modified accordion group open\n\n scope.status = {\n isItemOpen: new Array(scope.FlightCampaigns.length)\n };\n checkForCompletion();\n\n function openAssignment(_assignment, flightId, campaign, treatment, cindex) {\n scope.status.isItemOpen[cindex] = true;\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgCampaignAssignment.html',\n controller: 'AssignmentModalCtrl',\n size: 'md',\n keyboard: false,\n resolve: {\n assignment: function assignment() {\n return _objectSpread({}, _assignment);\n },\n info: function info() {\n return {\n flightId: +flightId,\n campaign: campaign,\n treatment: treatment\n };\n }\n }\n });\n modalInstance.closed.then(function () {\n scope.campaigns = CampaignFactory.getCampaignsByFlightId(+flightId);\n checkForCompletion();\n });\n }\n\n function previousTreatment(index) {\n if (index > 0) scope.currentTreatment = index - 1;\n }\n\n function nextTreatment(index, lenght) {\n if (index < lenght - 1) scope.currentTreatment = index + 1;\n }\n\n function isOpen(index) {\n return latestOpen == index;\n }\n\n function checkForCompletion() {\n if (scope.campaigns && scope.campaigns.CampaignsList && scope.campaigns.CampaignsList.length > 0) {\n scope.campaigns.CampaignsList.forEach(function (c) {\n c.Treatments.forEach(function (t) {\n var assignmentsWithStatus = t.Assignments.filter(function (a) {\n return +a.Status > 0;\n });\n t.CompleteFeedbacksCount = assignmentsWithStatus.length;\n var feedbacksCompleted = t.Assignments.every(function (a) {\n return a.Status > 0;\n });\n\n if (feedbacksCompleted) {\n t.FeedbacksCompleted = true;\n } else {\n t.FeedbacksCompleted = false;\n }\n });\n var campaignCompleted = c.Treatments.every(function (t) {\n return t.FeedbacksCompleted == true;\n });\n\n if (campaignCompleted) {\n c.TreamentsCompleted = true;\n } else {\n c.TreamentsCompleted = false;\n }\n });\n scope.FlightCampaigns = scope.campaigns;\n scope.flight.hasPendingFeedbacks = CampaignFactory.hasPendingFeedbacks(scope.campaigns);\n }\n }\n }\n\n return _ref = {\n restrict: 'E',\n scope: {\n campaigns: '@'\n },\n terminal: true,\n templateUrl: 'views/directives/campaigns.tpl.html'\n }, _defineProperty(_ref, \"scope\", false), _defineProperty(_ref, \"link\", link), _ref;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('crewMeals', crewMeals);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name crewMeals\r\n * @restrict E\r\n * @description\r\n * Implementation of crew meals\r\n *\r\n * Display the crew meals\r\n * @attr {String} dutyNo \r\n * @attr {String} dutyDay \r\n * @attr {String} flight-id\r\n * @example\r\n * Usage:\r\n * \r\n * \r\n * @ngInject\r\n */\n\n function crewMeals(CrewRouteFactory, CrewMealFactory, FlightFactory, $sce, $timeout) {\n /**\r\n * Initialize crewMeals\r\n * @memberof crewMeals\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\n function link(scope, element, attributes) {\n scope.togglePanel = togglePanel;\n scope.route = CrewRouteFactory.getCrewRouteFromStorage(scope.dutyNo, scope.dutyDay);\n scope.HasRegChanged = false;\n scope.noClicked = noClicked;\n scope.yesClicked = yesClicked;\n scope.submitRatingClicked = submitRatingClicked;\n scope.canceClicked = canceClicked;\n scope.clearFormData = clearFormData; //for flight page\n\n scope.isFlightPanel = scope.flightId !== \"\";\n scope.flightCrewMeals = null; //for route page\n\n scope.isRoutePanel = scope.flightId == null || scope.flightId === \"\";\n scope.routeCrewMeals = [];\n scope.showCrewMealsPanel = false; //Rating Form\n\n scope.ratingForm = {\n CateringMealId: '',\n FlightId: '',\n Rating: '',\n Comments: '',\n DidNotEatReasonId: ''\n };\n scope.submitRatingMessage = '';\n scope.showPanel = \"meals\";\n scope.DidNotEatReasons = [];\n scope.isOffline = !window.navigator.onLine;\n scope.popoverInfo = {\n title: $sce.trustAsHtml(' Attention'),\n contentHtml: $sce.trustAsHtml('
' + 'There is an aircraft change on your route. Please arrange to take your assigned meal with you.' + '
')\n };\n window.addEventListener('offline', function (e) {\n $timeout(scope.isOffline = !window.navigator.onLine);\n });\n window.addEventListener('online', function (e) {\n $timeout(scope.isOffline = !window.navigator.onLine);\n }); //Get scope values\n\n if (scope.isFlightPanel && scope.route) {\n var crewMeals = scope.route.CrewMeals;\n\n for (var i = 0; i < crewMeals.length; i++) {\n if (crewMeals[i].FlightId == scope.flightId) {\n scope.flightCrewMeals = new FlightCrewMeal(crewMeals[i]);\n scope.showCrewMealsPanel = true;\n break;\n }\n }\n\n scope.HasRegChanged = hasRegChanged(scope.flightId);\n }\n\n if (scope.isRoutePanel && scope.route && scope.route.CrewMeals.length > 0) {\n var crewMeals = scope.route.CrewMeals;\n\n for (var i = 0; i < crewMeals.length; i++) {\n scope.routeCrewMeals.push(new FlightCrewMeal(crewMeals[i]));\n scope.showCrewMealsPanel = true;\n }\n\n scope.HasRegChanged = hasRegChanged(crewMeals[0].FlightId);\n }\n\n if (!scope.isOffline && scope.showCrewMealsPanel) {\n CrewMealFactory.getCrewMealsDidNotEatReasons().then(function (res) {\n return scope.DidNotEatReasons = res;\n });\n } //FlightCrewMeal Constructor\n\n\n function FlightCrewMeal(flight) {\n this.FlightDate = moment(flight.FlightDate).format(\"DD/MM\");\n this.FlightNo = flight.FlightNo;\n this.FlightDeparture = flight.FlightDeparture;\n this.CrewMeals = \"\";\n this.CrewMealsDescriptions = [];\n\n for (var i = 0; i < Object.values(flight.CrewMealsCateringIds).length; i++) {\n if (i != 0) {\n this.CrewMeals += \" & \";\n }\n\n var crewMealDetails = CrewMealFactory.getCrewMealFromStorage(Object.values(flight.CrewMealsCateringIds)[i]);\n var hasRating = CrewMealFactory.hasRating(Object.keys(flight.CrewMealsCateringIds)[i]);\n this.CrewMeals += crewMealDetails.Title;\n this.CrewMealsDescriptions.push({\n CrewMealId: Object.keys(flight.CrewMealsCateringIds)[i],\n CateringMealId: crewMealDetails.CateringMealId,\n Title: crewMealDetails.Title,\n Description: crewMealDetails.Description,\n HasRating: hasRating\n });\n }\n } //Change Registration check\n\n\n function hasRegChanged(flightId) {\n var retVal = false;\n var flights = FlightFactory.getFlightsByFlightId(flightId);\n\n if (flights.length > 0) {\n var acTailNo = flights[0].AcTailNo;\n\n for (var i = 0; i < flights.length; i++) {\n if (flights[i].AcTailNo != acTailNo) {\n retVal = true;\n break;\n }\n }\n }\n\n return retVal;\n }\n /**\r\n * toggle Panel\r\n * @memberof crewMeals\r\n * @param {number} panelId\r\n */\n\n\n function togglePanel(panelId) {\n $('#' + panelId).toggle();\n }\n\n function noClicked(cateringMealId, crewMealId) {\n clearFormData(cateringMealId, crewMealId);\n scope.showPanel = \"didNotEatMeal\";\n }\n\n function yesClicked(cateringMealId, crewMealId) {\n clearFormData(cateringMealId, crewMealId);\n scope.showPanel = \"mealRating\";\n } //function checkConnection\n\n\n function clearFormData(cateringMealId, crewMealId) {\n scope.ratingForm.CateringMealId = cateringMealId;\n scope.ratingForm.FlightId = scope.flightId;\n scope.ratingForm.CrewMealId = crewMealId;\n scope.ratingForm.Rating = '';\n scope.ratingForm.DidNotEatReasonId = '';\n scope.ratingForm.Comments = '';\n scope.isOffline = !window.navigator.onLine;\n }\n\n function canceClicked() {\n scope.showPanel = \"meals\";\n }\n\n function submitRatingClicked() {\n scope.showPanel = \"loading\";\n CrewMealFactory.sendCrewMealsRatingReport(this.ratingForm).then(function (res) {\n return handleSubmitResponse(res);\n });\n }\n\n function handleSubmitResponse(res) {\n if (res.success) {\n var index = scope.flightCrewMeals.CrewMealsDescriptions.findIndex(function (x) {\n return x.CateringMealId == scope.ratingForm.CateringMealId;\n });\n scope.flightCrewMeals.CrewMealsDescriptions[index].HasRating = true;\n manageResponseMessage(\"success\", res.message);\n } else {\n manageResponseMessage(\"failure\", res.message);\n }\n }\n\n function manageResponseMessage(panelToShow, message) {\n scope.submitRatingMessage = message;\n scope.showPanel = panelToShow;\n $timeout(function () {\n scope.showPanel = \"meals\";\n }, 3000);\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/directives/crewMeals.tpl.html',\n scope: {\n dutyNo: '@',\n dutyDay: '@',\n flightId: '@'\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('eventHistory', eventHistory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name eventHistory\r\n * @restrict E\r\n * @description\r\n * Implementation of eventHistory\r\n * Initialize the Event History of report incidents (mockup view).\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function eventHistory() {\n return {\n restrict: 'E',\n templateUrl: 'views/directives/eventHistory.tpl.html'\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('flightCrew', flightCrew);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name flightCrew\r\n * @restrict E\r\n * @description\r\n * Initialize Flight Crew Information\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */\n\n function flightCrew() {\n function link(scope, element, attrs) {}\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: \"views/directives/flightCrew.tpl.html\",\n scope: {\n flight: '='\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('flightFooter', flightFooter);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name flightFooter\r\n * @restrict E\r\n * @description\r\n * Implementation of FlightFooter\r\n *\r\n * Initialize The flights Footer Template and its Navigation, Sync, Footer Functionality\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function flightFooter(orderByFilter, $location, $sce, $timeout, $interval, $filter, apiUrl, $uibModal, $route, SettingsMain, MemoFactory, MessageFactory, FlightFactory, UserFactory, DataCleanerFactory, CabinReportLocalEditFactory, ReportGuidFactory, SyncLogFactory, CrewRouteFactory, GroundDutyFactory) {\n /**\r\n * Initialize flightFooter and events\r\n * @memberof flightFooter\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attrs attribute of this element\r\n */\n function link(scope, element, attrs) {\n if (scope.flight) {\n /**\r\n * Find previous,next and current flight of the Route of the selected flight\r\n * @memberof flightFooter\r\n * @param {number} flightId input the Id of a Flight \r\n * @returns {Object} previous,next and current flight\r\n */\n var getPreviousAndNextFlights = function getPreviousAndNextFlights(flightId) {\n var nextFlight, previousFlight, currentFlight;\n var flights = FlightFactory.getFlightsByRoute(scope.flight.Route, scope.flight.DutyDate);\n flights = orderByFilter(flights, orderByDate, false);\n\n function orderByDate(item) {\n var date = new Date(item.ScheduledDeparture);\n return date;\n }\n\n for (var i = 0; i < flights.length; i++) {\n if (flights[i].FlightId == flightId) {\n if (i >= 1) {\n previousFlight = flights[i - 1];\n }\n\n if (i + 1 < flights.length) {\n nextFlight = flights[i + 1];\n }\n\n currentFlight = flights[i];\n }\n }\n\n return {\n nextFlight: nextFlight,\n previousFlight: previousFlight,\n currentFlight: currentFlight\n };\n };\n /**\r\n * It handles the cabin report when u want to navigate to another view\r\n * @memberof flightFooter\r\n * @param {String} state input the current state (view) \r\n * @param {number} flightId input the Id of a Flight \r\n * @param {Object} report input the cabin report \r\n */\n\n\n var handleIfReport = function handleIfReport(state, flightId, report) {\n if (state == 'report') {\n if (report == null) {\n report = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId);\n }\n\n var guid = report.ReportGuid;\n var status = report.Status; // delete the temp report\n\n CabinReportLocalEditFactory.deleteTempReport(); //reuse guid if this was a new report\n\n if (status == 'pending') ReportGuidFactory.restoreGuid(report.ReportGuid);\n }\n };\n /**\r\n * Open the Cabin Report for the selected Flight\r\n * @memberof flightFooter \r\n * @param {number} flightId input the Id of a Flight\r\n */\n\n\n var openReport = function openReport(flightId) {\n var user = UserFactory.getUser();\n var token = '';\n\n if (user != null) {\n token = user.token;\n token = encodeURIComponent(token);\n } // load the flight\n\n\n var flight = FlightFactory.getFlightFromStorage(flightId);\n\n if (flight == null) {\n // if not found, also check the local flights\n var flight = FlightFactory.getLocalFlightFromStorage(flightId);\n if (flight == null) return;\n } // load the reports\n\n\n var serverReportForThisUser = flight.getServerCabinReportForUser(user.aimsId);\n var serverReportsByAnotherUser = flight.getServerCabinReportsByAnotherUser(user.aimsId);\n var localReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId); // no stored local report\n\n if (localReport == null) {\n // has server report from this user and from other users\n if (serverReportForThisUser != null && serverReportsByAnotherUser.length > 0) {\n // show selection dialog\n openReportDialog(flightId);\n } // has server report only from this user\n else if (serverReportForThisUser != null && serverReportsByAnotherUser.length == 0) {\n $location.path(\"reportsHistory/\" + serverReportForThisUser.ReportId + \"/\" + flightId + \"/Cabin\");\n } // has server report only from other users\n else if (serverReportForThisUser == null && serverReportsByAnotherUser.length > 0) {\n // show selection dialog\n openReportDialog(flightId);\n } // no server reports, create a new local report directly\n else {\n $location.path(\"report/new:\" + -1 + \"/\" + flightId);\n }\n } // has stored local report\n else {\n // special case: has server report from this user, and not from\n // other users\n if (serverReportForThisUser != null && serverReportsByAnotherUser.length == 0) {\n // open the local report for editing\n $location.path(\"report/\" + localReport.ReportGuid);\n } // general case: has server report from this user or from other\n // users\n else if (serverReportForThisUser != null || serverReportsByAnotherUser.length > 0) {\n // show selection dialog\n openReportDialog(flightId);\n } // no server reports, open the local report directly\n else {\n // open the existing report for editing\n $location.path(\"report/\" + localReport.ReportGuid);\n }\n }\n };\n /**\r\n * Open a modal to choose an action when there is already a cabin report from another user\r\n * @memberof flightFooter \r\n * @param {number} flightId input the Id of a Flight\r\n */\n\n\n var openReportDialog = function openReportDialog(_flightId) {\n var modalInstance = $uibModal.open({\n templateUrl: './views/Dialogs/dlgOpenReport.html',\n controller: 'OpenReportDialogCtrl',\n size: 'md',\n resolve: {\n flightId: function flightId() {\n return _flightId;\n }\n }\n });\n modalInstance.result.then(function () {}, function () {});\n };\n /**\r\n * Open a modal from which u can Logout from the application\r\n * @memberof flightFooter \r\n */\n\n\n var logout = function logout() {\n var isSecure = UserFactory.isSecure();\n bootbox.dialog({\n message: (isSecure ? \"Due to the fact that you are working over a public computer, all stored data will be deleted on logout!

\" : \"You will be able to login again into the same account, even if there is no internet access.

\") + \"Please confirm that you wish to log out.\",\n title: \"User Logout\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n logout: {\n label: \"Logout\",\n className: \"btn-warning\",\n callback: function callback() {\n UserFactory.clearActiveUser();\n if (isSecure) DataCleanerFactory.deleteAllData();\n UserFactory.azSignOut();\n location.reload(true); // need to reload, in order for the\n // browser to check the cache.manifest\n // and discover any changes\n }\n }\n }\n });\n };\n /**\r\n * Redirects to Reset Device View\r\n * @memberof flightFooter \r\n */\n\n\n var resetDevice = function resetDevice() {\n SettingsMain.setEditingPage(null);\n $location.path(\"/reset\");\n };\n /**\r\n * Open a modal from which you can delete all available reports\r\n * @memberof flightFooter \r\n * @method\r\n */\n\n\n var deleteAllReports = function deleteAllReports() {\n bootbox.dialog({\n message: \"Use this process to clear your device from all locally stored Cabin Reports, in order to save up space, when available storage space is not sufficient for the application to function properly.

\" + \"

ATTENTION

\" + \"This action will delete all Cabin Reports from your device, including draft and completed ones not sent to the server.\",\n title: \"Application Logs Reset\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n danger: {\n label: \"Delete All Cabin Reports\",\n className: \"btn-danger\",\n callback: function callback() {\n DataCleanerFactory.deleteAllReports();\n $route.reload();\n bootbox.alert(\"All Cabin Reports have been successfully deleted.\", function () {});\n }\n }\n }\n });\n };\n /**\r\n * Navigate to Calendar View\r\n * @memberof flightFooter \r\n */\n\n\n var gotoCalendar = function gotoCalendar() {\n handleIfReport(state, flightId, report);\n SettingsMain.setEditingPage(null); // go to dashboard\n\n $location.path(\"/\");\n };\n /**\r\n * Navigate to Bucket Calendar View\r\n * @memberof flightFooter \r\n */\n\n\n var gotoBucketCalendar = function gotoBucketCalendar() {\n SettingsMain.setEditingPage(null);\n $location.path('/bucket');\n };\n /**\r\n * Navigate to FAQs View\r\n * @memberof flightFooter \r\n */\n\n\n var gotoFAQs = function gotoFAQs() {\n SettingsMain.setEditingPage(null);\n $location.path('/faqs');\n };\n /**\r\n * Navigate to Roster Requests\r\n * @memberof flightFooter \r\n */\n\n\n var gotoRequests = function gotoRequests() {\n SettingsMain.setEditingPage(null);\n $location.path('/rosterRequests');\n };\n /**\r\n * Navigate to Selected Flight Information View\r\n * @param {number} flightId input the Id of a Flight\r\n * @memberof flightFooter \r\n */\n\n\n var gotoFlight = function gotoFlight(flightId) {\n SettingsMain.setEditingPage(null);\n handleIfReport(state, flightId, report);\n $location.path('/flightinfo/' + flightId);\n };\n /**\r\n * Navigate to Messages View\r\n * @memberof flightFooter \r\n */\n\n\n var gotoMessageLibrary = function gotoMessageLibrary() {\n handleIfReport(state, flightId, report);\n $location.path('/messages');\n };\n /**\r\n * Navigate to the Current Flight's Information View\r\n * @memberof flightFooter \r\n */\n\n\n var gotoFlightInfo = function gotoFlightInfo() {\n gotoFlight(flightId);\n };\n /**\r\n * Navigate to Submit ticket view\r\n * @memberof flightFooter \r\n */\n\n\n var gotoTicket = function gotoTicket() {\n // go to Submit ticket view\n $location.path(\"/ticket\");\n };\n\n var goToSafetyReport = function goToSafetyReport(flightId) {\n $location.path('/safetyreport/cabincrewreport/' + flightId);\n };\n\n var goToFatigueReport = function goToFatigueReport(flightId) {\n $location.path('/safetyreport/fatiguereport/' + flightId);\n };\n /**\r\n * Open current's Flight Cabin Report\r\n * @memberof flightFooter \r\n */\n\n\n var openCabinReport = function openCabinReport() {\n SettingsMain.setEditingPage(null);\n openReport(flightId);\n };\n /**\r\n * Navigate to the Current Flight's Pax Information View\r\n * @memberof flightFooter \r\n */\n\n\n var gotoPaxInfo = function gotoPaxInfo() {\n SettingsMain.setEditingPage(null);\n handleIfReport(state, flightId, report);\n $location.path('/pax/' + flightId);\n };\n /**\r\n * Open current's Flight Cabin Crew Feedback Report\r\n * @memberof flightFooter \r\n */\n\n\n var openAssessment = function openAssessment() {\n SettingsMain.setEditingPage(null);\n $location.path(\"assessment/\" + flightId);\n };\n /**\r\n * Navigate to Memos Library\r\n * @memberof flightFooter \r\n */\n\n\n var gotoMemosLibrary = function gotoMemosLibrary() {\n SettingsMain.setEditingPage(null);\n handleIfReport(state, flightId, report);\n $location.path('/memos');\n }; //todo:: clean up\n // /**\n // * Get the latest Pax and Gate Informations\n // * @memberof flightFooter \n // */\n // function SynchPaxAndGates() {\n // var modalInstance = $uibModal.open({\n // templateUrl: 'views/Dialogs/dlgLightSync.html',\n // controller: 'SyncPaxCtrl',\n // size: 'md',\n // backdrop: 'static',\n // keyboard: false,\n // resolve: {\n // flightId: function () {\n // return flightId;\n // },\n // }\n // })\n // modalInstance.result.then(function () {\n // scope.lastSync = new Date().getTime();\n // }, function () {});\n // }\n\n /**\r\n * Opens refresh modal for results\r\n */\n\n\n var RefreshRoute = function RefreshRoute() {\n var _dutyNo = scope.flight.DutyNo;\n var _dutyDay = scope.flight.DutyDay;\n\n var _crewRouteDuty = CrewRouteFactory.getCrewRouteFromStorage(_dutyNo, _dutyDay);\n\n var groundDuties = GroundDutyFactory.getGroundDutiesByDutyNo(_dutyNo, _dutyDay);\n\n if (groundDuties.length > 0) {\n //there are ground duties in this crew route\n angular.forEach(groundDuties, function (groundDuty) {\n groundDuty.DutyType = \"Ground\";\n groundDuty.Start = groundDuty.DutyBegin;\n });\n }\n\n var flights = FlightFactory.getFlightsByDutyNo(_dutyNo, _dutyDay);\n\n if (flights.length > 0) {\n //there are flights in this crew route\n angular.forEach(flights, function (flight) {\n flight.DutyType = \"Flight\";\n flight.Start = flight.ScheduledDeparture;\n });\n }\n\n var crewRoute = groundDuties.concat(flights);\n crewRoute = $filter('orderBy')(crewRoute, 'Start', false);\n var modalInstance = $uibModal.open({\n templateUrl: 'views/CrewRoute/dlgCrewRouteRefresh.html',\n controller: 'CrewRouteRefreshModalCtrl',\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n crewroute: function crewroute() {\n return crewRoute;\n },\n crewRouteDuty: function crewRouteDuty() {\n return _crewRouteDuty;\n },\n dutyNo: function dutyNo() {\n return Number(_dutyNo);\n },\n dutyDay: function dutyDay() {\n return Number(_dutyDay);\n },\n forCurrentDay: function forCurrentDay() {\n return scope.flight.FlightDate;\n }\n }\n });\n modalInstance.result.then(function (transferData) {\n scope.lastSync = new Date().getTime();\n\n if (transferData.sync) {\n SyncLogFactory.forceSync();\n $location.path(\"/\"); //crew route has significantly changed\n } else if (transferData.refresh) {\n $route.reload(); //crew route was updated\n }\n });\n };\n /**\r\n * Show Popover that advices User to sync so he can get the latest Pax and Gate Informations\r\n * @memberof flightFooter \r\n */\n\n\n var showSyncPopover = function showSyncPopover() {\n var firstSyncWarning = departure - 4500000; //75 mintes before takeoff\n\n var secondSyncWarning = departure - 600000; //10 minutes before takeoff\n\n var now = new Date().getTime();\n var lastSync = scope.lastSync;\n\n if (now > firstSyncWarning && now < secondSyncWarning && (!lastSync || lastSync < firstSyncWarning) || now > secondSyncWarning && now < departure && (!lastSync || lastSync < secondSyncWarning)) {\n scope.enableSyncPopover = true;\n }\n };\n /**\r\n * Calculate the time difference of pax info list from now\r\n * @memberof flightFooter \r\n */\n\n\n var returnTimeDiff = function returnTimeDiff() {\n //time difference in minutes from: now and pax info list date\n scope.paxTimeDiffInMins = Math.round((new Date().getTime() - new Date(scope.paxInfo.LastRun).getTime()) / 60000);\n };\n\n var flightId = scope.flight.FlightId;\n var state = scope.state;\n var report = scope.report;\n var flights = getPreviousAndNextFlights(flightId);\n var user = UserFactory.getUser();\n var delay = 60000;\n var isAssessmentEnabled = SettingsMain.getIsAssessmentEnabled();\n var showAssessment = isAssessmentEnabled && scope.flight.assessment;\n var showFlightReport = scope.flight.LineStatus != 'na';\n var hasMultipleReports = showAssessment && !scope.flight.assessment.IsExist && showFlightReport;\n var reportsPopoverTemplateUrl = 'views/directives/reportsPopover.tpl.html';\n\n if (state == 'pax' || state == 'flight' && scope.paxInfo) {\n var now = new Date().getTime();\n var departure = new Date(scope.flight.ScheduledDeparture).getTime();\n\n if (departure < now) {\n var openSyncPopover = $interval(showSyncPopover, delay);\n }\n }\n\n if (state == 'pax' || state == 'flight') {\n if (scope.paxInfo && new Date(scope.flight.ScheduledDeparture).getTime() > new Date().getTime()) {\n returnTimeDiff();\n var showTimeDiff = $interval(returnTimeDiff, delay);\n }\n }\n\n scope.showAssessment = showAssessment;\n scope.showFlightReport = showFlightReport;\n scope.hasMultipleReports = hasMultipleReports;\n scope.reportsPopoverTemplateUrl = reportsPopoverTemplateUrl;\n scope.gotoFAQs = gotoFAQs;\n scope.gotoRequests = gotoRequests;\n scope.gotoFlight = gotoFlight;\n scope.previousFlight = flights.previousFlight;\n scope.nextFlight = flights.nextFlight;\n scope.gotoBucketCalendar = gotoBucketCalendar;\n scope.gotoCalendar = gotoCalendar;\n scope.gotoFlightInfo = gotoFlightInfo;\n scope.openCabinReport = openCabinReport;\n scope.logout = logout;\n scope.resetDevice = resetDevice;\n scope.deleteAllReports = deleteAllReports;\n scope.gotoMessageLibrary = gotoMessageLibrary;\n scope.gotoPaxInfo = gotoPaxInfo;\n scope.gotoMemosLibrary = gotoMemosLibrary;\n scope.RefreshRoute = RefreshRoute;\n scope.showPopover = false;\n scope.showMobileMenu = false;\n scope.userPosition = user.position;\n scope.openAssessment = openAssessment;\n scope.gotoTicket = gotoTicket;\n scope.goToSafetyReport = goToSafetyReport;\n scope.goToFatigueReport = goToFatigueReport;\n scope.syncWarning = $sce.trustAsHtml('
You are strongly advised to sync your device.
');\n scope.enableSyncPopover = false;\n scope.lastSync = null;\n element.on('$destroy', function () {\n $interval.cancel(openSyncPopover);\n $interval.cancel(showTimeDiff);\n });\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: \"views/Flight/footer.tpl.html\",\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('flightHeader', flightHeader);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name flightHeader\r\n * @restrict E\r\n * @description\r\n * Implementation of flightHeader\r\n * Initialize the template of the header while you are in the Flight Level\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */\n\n function flightHeader() {\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: \"views/Flight/header.tpl.html\",\n scope: false\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('groundCrew', groundCrew);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name groundCrew\r\n * @restrict E\r\n * @description\r\n * Initialize Trainer and Trainee Info\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */\n\n function groundCrew() {\n function link(scope, element, attrs) {\n scope.groundDuty = scope.duty;\n scope.toggleCrewList = toggleCrewList;\n scope.groundDuty.Trainees.forEach(function (relatedTrainees) {\n relatedTrainees.isCollapsed = false;\n relatedTrainees.dynamicSize = 10;\n });\n /**\r\n * @memberof GroundDutyCtrl\r\n * @name toggleCrewList\r\n * @description \r\n * Οnly show the first 10 trainees - if more then toggle\r\n */\n\n function toggleCrewList(relatedTrainees) {\n relatedTrainees.isCollapsed = !relatedTrainees.isCollapsed;\n if (relatedTrainees.isCollapsed) relatedTrainees.dynamicSize = relatedTrainees.CrewMembers.length;else relatedTrainees.dynamicSize = 10;\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: \"views/directives/groundCrew.tpl.html\",\n scope: {\n duty: '='\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('groundHeader', groundHeader);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name groundHeader\r\n * @restrict E\r\n * @description\r\n * Implementation of groundHeader (appears in groundDuty-info view)\r\n * Initialize the template of the header while you are in the Ground Duty Level\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */\n\n function groundHeader() {\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: \"views/GroundDuty/header.tpl.html\",\n scope: false\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('groundInfo', groundInfo);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name groundInfo\r\n * @restrict EA\r\n * @description\r\n * Implementation of groundInfo\r\n *\r\n * Initialize the ground information (Contacts,Hotels)\r\n * @attr {String} station The name of the station to get the ground information.\r\n * @example\r\n * Usage:\r\n *
\r\n * @ngInject\r\n */\n\n function groundInfo(AirportContactFactory, AirportHotelFactory) {\n /**\r\n * Calculates distinct HotelTypes (used for filtering results)\r\n * @memberof AirportHotelCtrl\r\n * @param {array} All the airport Hotels (object which containts Hotels property)\r\n * @return {array} The distinct HotelTypes as an array of strings\r\n */\n function findDistinctHotelTypes(items) {\n var unique = {};\n var distinct = [];\n\n for (var i in items) {\n if (items[i].Name && typeof unique[items[i].Name] == \"undefined\") {\n distinct.push(items[i].Name);\n }\n\n unique[items[i].Name] = 0;\n }\n\n return distinct;\n }\n /**\r\n * Used to properly display some Hotel Types, eg nulls\r\n * @memberof AirportHotelCtrl\r\n * @param {string} The Hotel type to examine and \"fix\"\r\n * @return {string} The \"fixed\" string for the given Hotel type (maybe the same as the input value if no fix is needed)\r\n */\n\n\n function printHotelType(HotelType) {\n if (!HotelType || HotelType == '') {\n console.log(HotelType);\n HotelType = '-no Hotel type-';\n }\n\n return HotelType;\n }\n /**\r\n * Calculates distinct ContactTypes (used for filtering results)\r\n * @memberof AirportContactCtrl\r\n * @param {array} All the airport contacts (object which containts Contacts property)\r\n * @return {array} The distinct ContactTypes as an array of strings\r\n */\n\n\n function findDistinctContactTypes(items) {\n var unique = {};\n var distinct = [];\n\n for (var i in items) {\n if (items[i].ContactType && typeof unique[items[i].ContactType] == \"undefined\") {\n distinct.push(items[i].ContactType);\n }\n\n unique[items[i].ContactType] = 0;\n }\n\n return distinct;\n }\n /**\r\n * Used to properly display some Contact Types, eg nulls\r\n * @memberof AirportContactCtrl\r\n * @param {string} The contact type to examine and \"fix\"\r\n * @return {string} The \"fixed\" string for the given contact type (maybe the same as the input value if no fix is needed)\r\n */\n\n\n function printContactType(contactType) {\n if (!contactType || contactType == '') return '-no contact type-';\n return contactType;\n }\n\n return {\n restrict: 'EA',\n terminal: true,\n templateUrl: 'views/directives/groundInfo.tpl.html',\n scope: true,\n link: function link($scope, element, attrs) {\n var stations = attrs.stations ? attrs.stations.split(\",\") : [];\n $scope.stationsInfo = [];\n $scope.filterHotelType = '';\n $scope.filterContactType = ''; //scope methods\n\n $scope.printHotelType = printHotelType;\n $scope.printContactType = printContactType;\n $scope.showInfo = showInfo;\n angular.forEach(stations, function (station) {\n var stationInfo = {};\n var flightDate = $scope.flight && $scope.flight.FlightDate ? $scope.flight.FlightDate : null;\n var contactInfo = AirportContactFactory.getAirportContacts(station);\n stationInfo.Contacts = contactInfo ? contactInfo.Contacts : [];\n stationInfo.ContactTypes = findDistinctContactTypes(stationInfo.Contacts);\n var hotelInfo = AirportHotelFactory.getAirportHotels(station, flightDate);\n stationInfo.Hotels = hotelInfo ? hotelInfo.Hotels : [];\n stationInfo.HotelTypes = findDistinctHotelTypes(stationInfo.Hotels);\n stationInfo.ActiveHotels = false;\n stationInfo.ActiveContacts = false;\n stationInfo.ActiveGeneralInfo = false;\n stationInfo.Name = station;\n\n if (stationInfo.Hotels.length > 0 || stationInfo.Contacts.length > 0) {\n $scope.stationsInfo.push(stationInfo);\n }\n });\n var oldViewStation = '';\n var oldViewType = '';\n\n function showInfo(station, type) {\n angular.forEach($scope.stationsInfo, function (stationInfo) {\n if (stationInfo.Name == station.Name) {\n if (type == 'Hotels') {\n stationInfo.ActiveHotels = !stationInfo.ActiveHotels;\n stationInfo.ActiveContacts = false;\n stationInfo.ActiveGeneralInfo = false;\n } else if (type == 'Contacts') {\n stationInfo.ActiveContacts = !stationInfo.ActiveContacts;\n stationInfo.ActiveHotels = false;\n stationInfo.ActiveGeneralInfo = false;\n } else if (type == 'General') {\n stationInfo.ActiveGeneralInfo = !stationInfo.ActiveGeneralInfo;\n stationInfo.ActiveHotels = false;\n stationInfo.ActiveContacts = false;\n }\n } else {\n stationInfo.ActiveHotels = false;\n stationInfo.ActiveContacts = false;\n stationInfo.ActiveGeneralInfo = false;\n }\n });\n }\n }\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('groundServices', groundServices);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name groundServices\r\n * @restrict E\r\n * @description\r\n * Implementation of ground services \r\n *\r\n * Display the ground services\r\n * @attr {String} arrival The flight arrival station.\r\n * @attr {String} departure The flight departure station.\r\n * @attr {String} flight-id The flight id.\r\n * @example\r\n * Usage:\r\n * \r\n * \r\n * @ngInject\r\n */\n\n function groundServices(GroundServicesFactory, CabinReportLocalEditFactory, CabinReportLocalEditCreatorFactory, FlightFactory, $sce) {\n /**\r\n * Initialize groundServices\r\n * @memberof groundServices\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\n function link(scope, element, attributes) {\n scope.togglePanel = togglePanel;\n scope.flight = FlightFactory.getFlightFromTotalFlights(scope.flightId);\n scope.isInFinalState = isInFinalState;\n scope.saveNewUsedState = saveNewUsedState;\n scope.DepartureGroundServices = [];\n scope.ArrivalGroundServices = [];\n scope.popoverInfo = {\n title: $sce.trustAsHtml(' Info'),\n contentHtml: $sce.trustAsHtml('
Contracted Services' + '
Non Contracted Services' + '
')\n };\n var report = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(scope.flightId);\n\n if (report == null) {\n if (scope.departure) {\n scope.DepartureGroundServices = GroundServicesFactory.getGroundServicesByStation(scope.departure);\n } // if (scope.arrival){\n // scope.ArrivalGroundServices = GroundServicesFactory.getGroundServicesByStation(scope.arrival);\n // }\n\n } else {\n report = CabinReportLocalEditFactory.checkForNewGroundServices(report);\n\n if (scope.departure) {\n scope.DepartureGroundServices = report.DepartureGroundServices;\n } // if (scope.arrival){\n // scope.ArrivalGroundServices = report.ArrivalGroundServices;\n // }\n\n }\n /**\r\n * Check if the report is in a final state so that we cant edit any more\r\n * @memberof groundServices\r\n * @returns {boolean} true if final, false otherwise\r\n */\n\n\n function isInFinalState() {\n var isInFinalState = scope.flight.LineStatus === 'na' || scope.flight.LineStatus === 'stored' || scope.flight.LineStatus === 'storedotheruser' || scope.flight.LineStatus === 'stored+otheruser' || scope.flight.LineStatus === 'synched' || scope.flight.LineStatus === 'synchedotheruser';\n return isInFinalState;\n }\n /**\r\n * When a ground service usage is toggled on or off,\r\n * create the report if it doesnt exist\r\n * or just save the changes\r\n * @memberof groundServices\r\n */\n\n\n function saveNewUsedState() {\n //if report is pending, it doesnt exist yet. create it\n if (scope.flight.LineStatus === 'pending' || scope.flight.LineStatus === 'pendingoverdue') {\n report = CabinReportLocalEditCreatorFactory.createNewLocalReportForFlight(scope.flightId);\n\n if (scope.departure) {\n report.DepartureGroundServices = scope.DepartureGroundServices;\n } else {\n report.DepartureGroundServices = [];\n } // if (scope.arrival){\n // report.ArrivalGroundServices = scope.ArrivalGroundServices;\n // }else{\n // report.ArrivalGroundServices = [];\n // }\n\n\n report.Status = 'draft';\n report.saveReport();\n FlightFactory.updateFlightFromReport(report);\n }\n\n CabinReportLocalEditFactory.setCabinReportToStorage(report);\n } //TODO : find a more angular way (EPAP)\n\n /**\r\n * toggle Panel\r\n * @memberof groundServices\r\n * @param {number} panelId\r\n */\n\n\n function togglePanel(panelId) {\n $('#' + panelId).toggle();\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/directives/groundServices.tpl.html',\n scope: {\n arrival: '@',\n departure: '@',\n flightId: '@'\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('issues', issues);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name issues\r\n * @restrict EA\r\n * @description\r\n * Implementation of issues\r\n *\r\n * Initialize the issues telplates for the cabin report form according to their type\r\n * @attr {String} type The name of the type to initialize the according Issue template.\r\n * @example\r\n * Usage:\r\n *
\r\n * @ngInject\r\n */\n\n function issues() {\n function _templateUrl(type) {\n var template = 'views/reportItems/empty.html';\n\n if (type == 'bar') {\n template = 'views/Report/bar.tpl.html';\n } else if (type == 'medicalincidents') {\n template = 'views/Report/medicalIncidents.tpl.html';\n } else if (type == 'securitycheck') {\n template = 'views/Report/securityCheck.tpl.html';\n } else if (type == 'specialmeals') {\n template = 'views/Report/specialMeals.tpl.html';\n } else if (type == 'supplies') {\n template = 'views/Report/supplies.tpl.html';\n } else if (type == 'travelvalues') {\n template = 'views/Report/travelValues.tpl.html';\n } else if (type == 'um') {\n template = 'views/Report/um.tpl.html';\n } else if (type == 'various') {\n template = 'views/Report/various.tpl.html';\n } else if (type == 'wateruplift') {\n template = 'views/Report/waterUplift.tpl.html';\n } else if (type == 'groundservices') {\n template = 'views/Report/groundServices.tpl.html';\n } else if (type == 'changedseats') {\n template = 'views/Report/changedSeats.tpl.html';\n } else if (type == 'upgd') {\n template = 'views/Report/upgd.tpl.html';\n } else if (type == 'incompleteServices') {\n template = 'views/Report/incompleteServices.tpl.html';\n } // else if(type=='boardingtimes'){\n // \ttemplate='views/Report/boardingTimes.tpl.html';\n // }\n // else if(type=='disembarkationtimes'){\n // \ttemplate='views/Report/disembarkationTimes.tpl.html';\n // }\n else if (type == 'luggage') {\n template = 'views/Report/luggage.tpl.html';\n }\n\n return template;\n }\n\n return {\n restrict: 'EA',\n terminal: false,\n templateUrl: function templateUrl(element, attrs) {\n return _templateUrl(attrs.type);\n },\n scope: false\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('mainFooter', mainFooter);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name mainFooter\r\n * @restrict E\r\n * @description\r\n * Implementation of mainFooter\r\n * Initialize The main Footer Template and its Navigation, Sync, Footer Functionality\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */\n\n function mainFooter($location, SettingsMain, UserFactory, $uibModal, MessageFactory, DataCleanerFactory, $route, MemoFactory, FaqFactory, RequestFactory, $sce, $timeout, FlightFactory, LeaveRequestFactory, PassengerMealServiceFactory) {\n /**\r\n * Initialize mainFooter and events\r\n * @memberof mainFooter\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attrs attribute of this element\r\n */\n function link(scope, element, attrs) {\n var messagesCount = 0;\n var messages = [];\n var unreadMessagesCount = 0;\n var memosCount = 0;\n var memos = [];\n var faqs = [];\n var newFAQCount = 0;\n var updatedFAQCount = 0;\n /**\r\n * Open a modal from which u can Logout from the application\r\n * @memberof mainFooter \r\n */\n\n function logout() {\n var isSecure = UserFactory.isSecure();\n bootbox.dialog({\n message: (isSecure ? \"Due to the fact that you are working over a public computer, all stored data will be deleted on logout!

\" : \"You will be able to login again into the same account, even if there is no internet access.

\") + \"Please confirm that you wish to log out.\",\n title: \"User Logout\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n logout: {\n label: \"Logout\",\n className: \"btn-warning\",\n callback: function callback() {\n UserFactory.clearActiveUser();\n if (isSecure) DataCleanerFactory.deleteAllData();\n UserFactory.azSignOut();\n location.reload(true); // need to reload, in order for the\n // browser to check the cache.manifest\n // and discover any changes\n }\n }\n }\n });\n }\n /**\r\n * Redirects to Reset Device View\r\n * @memberof mainFooter \r\n */\n\n\n function resetDevice() {\n $location.path(\"/reset\");\n }\n /**\r\n * Open a modal from which you can delete all available reports\r\n * @memberof mainFooter \r\n * @method\r\n */\n\n\n function deleteAllReports() {\n bootbox.dialog({\n message: \"Use this process to clear your device from all locally stored Cabin Reports, in order to save up space, when available storage space is not sufficient for the application to function properly.

\" + \"

ATTENTION

\" + \"This action will delete all Cabin Reports from your device, including draft and completed ones not sent to the server.\",\n title: \"Application Logs Reset\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n danger: {\n label: \"Delete All Cabin Reports\",\n className: \"btn-danger\",\n callback: function callback() {\n DataCleanerFactory.deleteAllReports();\n $route.reload();\n bootbox.alert(\"All Cabin Reports have been successfully deleted.\", function () {});\n }\n }\n }\n });\n }\n /**\r\n * Navigate to Calendar View\r\n * @memberof mainFooter \r\n */\n\n\n function gotoCalendar() {\n SettingsMain.setEditingPage(null); // go to dashboard\n\n $location.path(\"/\");\n }\n /**\r\n * Navigate to Submit ticket view\r\n * @memberof mainFooter \r\n */\n\n\n function gotoTicket() {\n // go to Submit ticket view\n $location.path(\"/ticket\");\n }\n /**\r\n * Navigate to Messages View\r\n * @memberof mainFooter \r\n */\n\n\n function gotoMessageLibrary() {\n $location.path('/messages');\n }\n /**\r\n * Navigate to Memos Library\r\n * @memberof mainFooter \r\n */\n\n\n function gotoMemos() {\n $location.path('/memos');\n }\n /**\r\n \t* Navigate to Bucket\r\n \t* @memberof mainFooter \r\n \t*/\n\n\n function gotoBucketCalendar() {\n $location.path('/bucket');\n }\n /**\r\n * Navigate to FAQs View\r\n * @memberof mainFooter \r\n */\n\n\n function gotoFAQs() {\n $location.path('/faqs');\n }\n /**\r\n * Navigate to Roster Requests View\r\n * @memberof mainFooter \r\n */\n\n\n function gotoRequests() {\n $location.path(\"/rosterRequests\");\n }\n /**\r\n * Navigate to FAQs View\r\n * @memberof mainFooter \r\n */\n\n\n function gotoLeaveRequests() {\n $location.path('/leaverequest');\n }\n\n function gotoMealLibrary() {\n $location.path('/mealLibrary');\n }\n /**\r\n * Open the \"Search Flight Info\" Modal\r\n * @memberof CalendarCtrl\r\n */\n\n\n function openSearchFlightsModal() {\n var modalInstance = $uibModal.open({\n templateUrl: './views/SearchFlights/dlgSearchFlights.html',\n controller: 'SearchFlightsCtrl',\n size: 'md',\n backdrop: 'static',\n keyboard: false\n });\n }\n\n messages = MessageFactory.getMessagesFromStorage();\n messagesCount = messages.length;\n\n for (var i = 0; i < messages.length; i++) {\n if (messages[i].ReadDt == null) {\n unreadMessagesCount++;\n }\n }\n\n MemoFactory.getNotHiddenMemos(function (results) {\n scope.memosCount = results.length;\n });\n faqs = FaqFactory.getFAQsFromStorage();\n\n for (var i = 0; i < faqs.length; i++) {\n if (faqs[i].newItems) {\n newFAQCount += faqs[i].newItems;\n }\n\n if (faqs[i].updatedItems) {\n updatedFAQCount += faqs[i].updatedItems;\n }\n }\n\n scope.messagesCount = messagesCount;\n scope.unreadMessagesCount = unreadMessagesCount;\n scope.logout = logout;\n scope.resetDevice = resetDevice;\n scope.deleteAllReports = deleteAllReports;\n scope.gotoMessageLibrary = gotoMessageLibrary;\n scope.gotoMemos = gotoMemos;\n scope.gotoBucketCalendar = gotoBucketCalendar;\n scope.memosCount = memosCount;\n scope.gotoFAQs = gotoFAQs;\n scope.gotoRequests = gotoRequests;\n scope.gotoLeaveRequests = gotoLeaveRequests;\n scope.newFAQCount = newFAQCount;\n scope.updatedFAQCount = updatedFAQCount;\n scope.gotoCalendar = gotoCalendar;\n scope.showPopover = false;\n scope.gotoTicket = gotoTicket;\n scope.leaveRequestInformation = LeaveRequestFactory.getLeaveRequestInformation();\n scope.openSearchFlightsModal = openSearchFlightsModal;\n scope.gotoMealLibrary = gotoMealLibrary;\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: \"views/Main/footer.tpl.html\",\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('memosByCategory', memosByCategory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name memosByCategory\r\n * @restrict E\r\n * @description\r\n * Implementation of memosByCategory\r\n * Initialize the panels with memos group by category.\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function memosByCategory(MemoFactory, MemoImagesFactory, $uibModal, DataCleanerFactory, GroundDutyFactory, FlightFactory) {\n function link($scope, attrs) {\n $scope.togglePanel = togglePanel;\n var Id = $scope.id;\n /**\r\n * toggle Panel\r\n * @memberof memosByCategory\r\n * @param {number} panelId\r\n */\n\n function togglePanel(panelId) {\n $('#' + panelId).toggle();\n } //Initialize Memos\n\n\n if ($scope.type == \"duty\" || $scope.type == \"d\") {\n MemoFactory.getMemosForCrewRoute(Id, $scope.day, function (results) {\n $scope.memos = filterMemos(results);\n });\n } else if ($scope.type == \"ground\" || $scope.type == \"g\") {\n MemoFactory.getMemosForGroundDuty(Id, function (results) {\n $scope.memos = filterMemos(results);\n });\n } //(attrs.type == \"flight\" || attrs.type == \"f\") default Flight type\n else {\n MemoFactory.getMemosForFlight(Id, function (results) {\n $scope.memos = filterMemos(results);\n });\n }\n /**\r\n * filter memos\r\n * @memberof memosByCategory\r\n * @param {object} data\r\n */\n\n\n function filterMemos(data) {\n //normalize memos\n var distinctMemos = normalizeMemos(data);\n\n if (distinctMemos.length != data.length) {\n MemoFactory.getMemosFromStorage(function (allMemos) {\n var distinctMemosAll = normalizeMemos(allMemos);\n MemoImagesFactory.getMemoImagesFromStorage(function (allMemoImages) {\n var distinctMemoImagesAll = normalizeMemoImages(allMemoImages);\n recreateIndexedDB(distinctMemosAll, allMemoImages);\n });\n });\n }\n\n var memosByCategory = [];\n\n for (var i = 0; i < distinctMemos.length; i++) {\n var memo = distinctMemos[i];\n\n if (!memosByCategory.filter(function (e) {\n return e.CategoryId != undefined && e.CategoryId == memo.CategoryId || e.Category != undefined && memo.Category == e.Category;\n }).length > 0) {\n memosByCategory.push({\n CategoryId: memo.CategoryId,\n Category: memo.Category,\n memoList: [memo]\n });\n } else if (memosByCategory.filter(function (e) {\n return e.CategoryId != undefined && e.CategoryId == memo.CategoryId || e.Category != undefined && memo.Category == e.Category;\n }).length > 0) {\n memosByCategory.filter(function (object) {\n if (object.CategoryId != undefined && object.CategoryId == memo.CategoryId || object.Category != undefined && memo.Category == object.Category) {\n return object;\n }\n\n ;\n })[0].memoList.push(memo);\n }\n }\n\n return memosByCategory;\n }\n\n function recreateIndexedDB(distinctMemosAll, distinctMemosImagesAll) {\n //delete indexdb\n var q = DataCleanerFactory.deleteIndexedDB();\n q.then(function () {\n MemoFactory.setMemosToStorage(distinctMemosAll);\n MemoImagesFactory.setMemoImagesToStorage(distinctMemosImagesAll); //save normalize data to indexedDB\n\n LogService.debug(\"Recreated IndexedDB\");\n });\n q[\"catch\"](function (ex) {\n console.log(ex);\n });\n }\n\n function normalizeMemos(data) {\n var distinctData = [];\n\n if (data && data.length > 1) {\n var sortData = data.dynamicSort(\"Id\");\n\n for (var i = 0; i < sortData.length - 1; i++) {\n if (sortData[i + 1].Id == sortData[i].Id) {\n //swap rows in list - check lastUpdated property, latest at the end\n if (sortData[i].LastUpdated && sortData[i + 1].LastUpdated) {\n var memoDateA = new Date(sortData[i].LastUpdated);\n var memoDateB = new Date(sortData[i + 1].LastUpdated);\n\n if (memoDateA.getTime() > memoDateB.getTime()) {\n var temp = sortData[i + 1];\n sortData[i + 1] = sortData[i];\n sortData[i] = temp;\n }\n }\n } else {\n distinctData.push(sortData[i]);\n }\n }\n\n distinctData.push(sortData[sortData.length - 1]);\n } else {\n distinctData = data;\n }\n\n return distinctData;\n }\n\n function normalizeMemoImages(data) {\n var distinctData = [];\n\n if (data && data.length > 1) {\n var sortData = data.dynamicSort(\"imageId\");\n\n for (var i = 0; i < sortData.length - 1; i++) {\n if (!(sortData[i + 1].imageId == sortData[i].imageId)) {\n distinctData.push(sortData[i]);\n }\n }\n\n distinctData.push(sortData[sortData.length - 1]);\n } else {\n distinctData = data;\n }\n\n return distinctData;\n }\n\n $scope.openMemo = openMemo;\n /**\r\n * Open modal to see information for the selected Memo\r\n * @memberof memosByCategory\r\n * @param {object} memo A memo object\r\n */\n\n function openMemo(_memo) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgMemo.html',\n controller: 'MemoModalCtrl',\n size: 'lg',\n keyboard: false,\n resolve: {\n memo: function memo() {\n return _memo;\n }\n }\n });\n modalInstance.result.then(function () {\n if (_memo.ReadDt == null) {\n _memo.ReadDt = new Date();\n MemoFactory.saveOneMemoToStorage(_memo);\n\n if ($scope.type == \"ground\") {\n MemoFactory.markGroundDutiesUnread();\n }\n }\n });\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: \"views/directives/memosByCategoryPanel.tpl.html\",\n scope: {\n type: '@',\n id: '=',\n day: '='\n },\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('reportsPanel', reportsPanel);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name reportsPanel\r\n * @restrict E\r\n * @description\r\n * Implementation of reportsPanel\r\n * Initialize the panels with reports.\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function reportsPanel(SettingsMain, $location, $anchorScroll, enableWaterUpliftReporting, waterUpliftSupportingAcTypes, defaultCalendarDate) {\n function link($scope, element, attrs) {\n //Initialize CSS classes\n $scope.togglePanel = togglePanel;\n $scope.showSafetyReport = showSafetyReport(); //$scope.showCampaignsFeedback = CampaignFactory.hasPendingFeedbacks($scope.flight.FlightId);\n\n $scope.goToCampaignsPanel = function () {\n $location.hash('campaigns');\n $anchorScroll();\n };\n\n if (attrs.assessmentOnly != \"true\") {\n $scope.showReports = true;\n $scope.getBottomClass = getBottomClass;\n $scope.getTextClass = getTextClass;\n $scope.getAssessmentTextClass = getAssessmentTextClass;\n $scope.getTopClass = getTopClass;\n $scope.hasIcon = hasIcon;\n $scope.isWaterUpliftRequired = isWaterUpliftRequired;\n } else {\n //Assessment only\n $scope.showReports = false;\n $scope.getBottomClass = \"\";\n\n if ($scope.crewRouteDuty && $scope.crewRouteDuty.AssessmentInfo) {\n $scope.getAssessmentTextClass = \"\";\n updateClassesForAssessment();\n $scope.assessmentStatus = $scope.crewRouteDuty.AssessmentInfo.IsExist || $scope.crewRouteDuty.AssessmentInfo.Status == \"Stored\" ? \"synched\" : $scope.crewRouteDuty.AssessmentInfo.Status;\n $scope.openAssessment = openAssessment;\n }\n }\n\n function showSafetyReport() {\n if (attrs.assessmentOnly != \"true\") {\n var today = new Date().toUTC();\n\n if (defaultCalendarDate) {\n today = new Date(defaultCalendarDate).toUTC();\n }\n\n var flightDate = new Date($scope.flight.FlightDate);\n var trimmedToday = new Date(today);\n var trimmedFlightDate = new Date(flightDate);\n var diffDays = Date.DifferenceInDays(trimmedToday.trimTime(), trimmedFlightDate.trimTime());\n return diffDays <= 0;\n } else {\n return false;\n }\n }\n\n function isWaterUpliftRequired() {\n var today = new Date($scope.flight.FlightDate);\n return (today.getDate() == 1 || today.getDate() == 15) && enableWaterUpliftReporting && waterUpliftSupportingAcTypes.includes($scope.flight.AcType);\n }\n /**\r\n * toggle Panel\r\n * @memberof reportsPanel\r\n * @param {number} panelId\r\n */\n\n\n function togglePanel(panelId) {\n $('#' + panelId).toggle();\n }\n /**\r\n * Return the text ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\n\n\n function getTextClass() {\n var classname = \"\";\n if ($scope.flight.LineStatus === 'na') classname = \"text-gray\";else if ($scope.flight.LineStatus === 'pending') classname = \"text-blue\";else if ($scope.flight.LineStatus === 'pendingoverdue') classname = \"text-blue\";else if ($scope.flight.LineStatus === 'draft' || $scope.flight.LineStatus === 'draftotheruser') {\n classname = \"text-orange\";\n } else if ($scope.flight.LineStatus === 'completed' || $scope.flight.LineStatus === 'completedotheruser') {\n classname = \"text-purple\";\n } else if ($scope.flight.LineStatus === 'stored' || $scope.flight.LineStatus === 'storedotheruser' || $scope.flight.LineStatus === 'stored+otheruser' || $scope.flight.LineStatus === 'synched' || $scope.flight.LineStatus === 'synchedotheruser') {\n classname = \"text-green\";\n }\n return classname;\n }\n /**\r\n * Return the panel upper ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\n\n\n function getTopClass() {\n var classname = \"\";\n if ($scope.flight.LineStatus === 'na') classname = \"border-top-gray\";else if ($scope.flight.LineStatus === 'pending') classname = \"border-top-blue\";else if ($scope.flight.LineStatus === 'pendingoverdue') classname = \"border-top-blue\";else if ($scope.flight.LineStatus === 'draft' || $scope.flight.LineStatus === 'draftotheruser') {\n classname = \"border-top-orange\";\n } else if ($scope.flight.LineStatus === 'completed' || $scope.flight.LineStatus === 'completedotheruser') {\n classname = \"border-top-purple\";\n } else if ($scope.flight.LineStatus === 'stored' || $scope.flight.LineStatus === 'storedotheruser' || $scope.flight.LineStatus === 'stored+otheruser' || $scope.flight.LineStatus === 'synched' || $scope.flight.LineStatus === 'synchedotheruser') {\n classname = \"border-top-green\";\n }\n return classname;\n }\n /**\r\n * Return the panel border ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\n\n\n function getBottomClass() {\n var classname = \"\";\n if ($scope.flight.LineStatus === 'na') classname = \"border-bottom-gray\";else if ($scope.flight.LineStatus === 'pending') classname = \"border-bottom-blue\";else if ($scope.flight.LineStatus === 'pendingoverdue') classname = \"border-bottom-blue\";else if ($scope.flight.LineStatus === 'draft' || $scope.flight.LineStatus === 'draftotheruser') {\n classname = \"border-bottom-orange\";\n } else if ($scope.flight.LineStatus === 'completed' || $scope.flight.LineStatus === 'completedotheruser') {\n classname = \"border-bottom-purple\";\n } else if ($scope.flight.LineStatus === 'stored' || $scope.flight.LineStatus === 'storedotheruser' || $scope.flight.LineStatus === 'stored+otheruser' || $scope.flight.LineStatus === 'synched' || $scope.flight.LineStatus === 'synchedotheruser') {\n classname = \"border-bottom-green\";\n }\n return classname;\n }\n /**\r\n * If report from another user exists, show icon\r\n * @memberof FlightInfoCtrl\r\n * @returns {boolean} hasIcon\r\n */\n\n\n function hasIcon() {\n var hasIcon = false;\n\n if ($scope.flight.LineStatus === 'draftotheruser' || $scope.flight.LineStatus === 'completedotheruser' || $scope.flight.LineStatus === 'storedotheruser' || $scope.flight.LineStatus === 'stored+otheruser' || $scope.flight.LineStatus === 'synchedotheruser') {\n hasIcon = true;\n }\n\n return hasIcon;\n }\n /**\r\n * Returns the assessment Text Class\r\n * @memberof FlightInfoCtrl\r\n * @return {string} classname\r\n */\n\n\n function getAssessmentTextClass() {\n var classname = \"\";\n\n if ($scope.flight.assessment) {\n if ($scope.flight.assessment.IsExist || $scope.flight.assessment.Status === 'Stored' || $scope.flight.assessment.Status === 'Outdated') {\n classname = \"text-green\";\n } else if ($scope.flight.assessment.Status === 'Pending') classname = \"text-blue\";else if ($scope.flight.assessment.Status === 'Draft') {\n classname = \"text-orange\";\n } else if ($scope.flight.assessment.Status === 'Completed') {\n classname = \"text-purple\";\n }\n }\n\n return classname;\n }\n /**\r\n * Return the panel border & text ccs class accoriding to assessment status \r\n * @memberof reportsPanel\r\n * @returns {string} cssClass\r\n */\n\n\n function updateClassesForAssessment() {\n //default values\n $scope.getBottomClass = \"\";\n $scope.getAssessmentTextClass = \"\";\n\n if ($scope.crewRouteDuty && $scope.crewRouteDuty.AssessmentInfo) {\n if ($scope.crewRouteDuty.AssessmentInfo.IsExist || $scope.crewRouteDuty.AssessmentInfo.Status == \"Stored\") {\n $scope.getBottomClass = \"border-bottom-green\";\n $scope.getAssessmentTextClass = \"text-green\";\n } else if ($scope.crewRouteDuty.AssessmentInfo.Status == \"Pending\") {\n $scope.getBottomClass = \"border-bottom-blue\";\n $scope.getAssessmentTextClass = \"text-blue\";\n } else if ($scope.crewRouteDuty.AssessmentInfo.Status == \"Draft\") {\n $scope.getBottomClass = \"border-bottom-orange\";\n $scope.getAssessmentTextClass = \"text-orange\";\n } else if ($scope.crewRouteDuty.AssessmentInfo.Status == \"Completed\") {\n $scope.getBottomClass = \"border-bottom-purple\";\n $scope.getAssessmentTextClass = \"text-purple\";\n }\n }\n }\n /**\r\n * Open current's Flight Cabin Crew Feedback Report\r\n * @memberof flightFooter \r\n */\n\n\n function openAssessment() {\n SettingsMain.setEditingPage(null);\n $location.path(\"assessment/\" + $scope.firstFlightId);\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: \"views/directives/reportsPanel.tpl.html\",\n scope: true,\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('securitySearch', securitySearch);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name securitySearch\r\n * @restrict E\r\n * @description\r\n * Implementation of securitySearch\r\n * Initialize the panel with previous flight info.\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function securitySearch(AircaftPositionsFactory, FlightFactory) {\n function link($scope) {\n var showSecurityMsg = false;\n var securitySearchRequired = null;\n var DepartureUK = null;\n var DepartureEU = null;\n var DepartureCDG = null;\n var PreviousEU = null;\n var aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId($scope.id);\n var flightInfo = FlightFactory.getFlightFromStorage($scope.id);\n\n if (flightInfo) {\n DepartureUK = flightInfo.DepartureCountry == \"UNITED KINGDOM\";\n DepartureEU = flightInfo.DepartureEU;\n DepartureCDG = flightInfo.Departure == \"CDG\"; // RULE 1: Current Departure Airport is UK\n // RULE 2: Current Departure Airport is Non EU\n // RULE 3: Current Departure Airport is CDG Airport\n\n if (DepartureUK || !DepartureEU || DepartureCDG) {\n securitySearchRequired = true;\n } else {\n securitySearchRequired = false;\n }\n }\n\n if (aircaftPositions) {\n // RULE 4: Previous Origin Airport is Non EU\n PreviousEU = aircaftPositions.PreviousEU;\n\n if (!PreviousEU) {\n securitySearchRequired = true;\n } else {\n securitySearchRequired = false;\n }\n }\n\n if (securitySearchRequired != null) {\n showSecurityMsg = true;\n }\n\n $scope.showSecurityMsg = showSecurityMsg;\n $scope.securitySearchRequired = securitySearchRequired;\n $scope.aircaftPositions = aircaftPositions;\n }\n\n return {\n restrict: 'E',\n templateUrl: \"views/directives/securitySearch.tpl.html\",\n scope: {\n id: '='\n },\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('showerrormessage', showerrormessage);\n /**\r\n * @ngdoc directive\r\n * @name showerrormessage\r\n * @restrict EA\r\n * @description\r\n * Implementation of show error message\r\n * @attr {String} message: the error message.\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function showerrormessage() {\n function link($scope, element, attrs) {\n $scope.errorMessage = attrs.message;\n $scope.hasMessage = attrs.message != null && attrs.message.length > 0;\n }\n\n return {\n restrict: 'E',\n template: '
{{errorMessage}}
',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('ssr', ssr);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name ssr\r\n * @restrict EA\r\n * @description\r\n * Implementation of issues\r\n *\r\n * Initialize the special service template\r\n * @attr {String} format The name of the format to initialize the ssr.\r\n * @example\r\n * Usage:\r\n *
\r\n * @ngInject\r\n */\n\n function ssr($sce, ssrCodes, waterUpliftSupportingAcTypes) {\n return {\n restrict: 'EA',\n terminal: true,\n templateUrl: 'views/directives/ssr.tpl.html',\n scope: {\n paxInfo: '=',\n flight: '='\n },\n link: function link($scope, element, attrs) {\n $scope.format = attrs.format;\n $scope.VIP = detailedInfo('VIP');\n $scope.UPGD = detailedInfo('UPGD');\n $scope.FQTVGold = detailedInfo('FQTVGold');\n $scope.FQTVSilver = detailedInfo('FQTVSilver');\n $scope.UMNR = detailedInfo('UMNR');\n $scope.PRM = detailedInfo('WCBD,WCBW,WCHC,WCHR,WCHS,WCLB,WCMP,WCOB');\n $scope.DEAF = detailedInfo('DEAF');\n $scope.BLND = detailedInfo('BLND');\n $scope.DPNA = detailedInfo('DPNA');\n $scope.DEP = detailedInfo('DEPA,DEPU,ESCD');\n $scope.INAD = detailedInfo('INAD');\n $scope.MEDA = detailedInfo('AOXY,MEDA,MEQT,POXY');\n $scope.CBBG = detailedInfo('CBBG');\n $scope.OTH = detailedInfo('AVIH,BIKE,EMIG,ESAN,EXST,FAMS,GPST,HAJJ,PETC,SVAN,WEAP,XBGS,MAAS');\n $scope.UndeliveredChargeableSeats = detailedInfo('UndeliveredChargeableSeats');\n $scope.showFQTVGold = false;\n $scope.showFQTVSilver = false;\n $scope.showUMNR = false;\n $scope.showPRM = false;\n $scope.showDEAF = false;\n $scope.showBLND = false;\n $scope.showDPNA = false;\n $scope.showDEP = false;\n $scope.showINAD = false;\n $scope.showMEDA = false;\n $scope.showCBBG = false;\n $scope.showOTH = false;\n $scope.showIrregularites = false;\n $scope.showVIP = false;\n $scope.hasZones = hasZones;\n $scope.zoneC = getZone('C');\n $scope.zoneY = getZone('Y');\n $scope.waterQuantity = getWaterQuantity();\n $scope.supportsWaterUpliftAcType = supportsWaterUpliftAcType();\n $scope.UMNRDetails = umnrInfo('UMNR');\n\n function umnrInfo(umnr) {\n if ($scope.paxInfo) {\n $scope.totalUMNR = [];\n $scope.paxInfo.Seatmap.forEach(function (row) {\n row.Columns.forEach(function (column) {\n if (column.SSR.IsUMNR) $scope.totalUMNR.push(column);\n });\n });\n }\n }\n\n function supportsWaterUpliftAcType() {\n return waterUpliftSupportingAcTypes.includes($scope.flight.AcType);\n }\n\n function getWaterQuantity() {\n var totalPax = $scope.flight.BookedC + $scope.flight.BookedY;\n var startDate = moment($scope.flight.ScheduledDeparture);\n var endDate = moment($scope.flight.ScheduledArrival);\n var duration = moment.duration(endDate.diff(startDate)).asHours();\n var waterQuantity = (0, 18 * totalPax * duration) / 200;\n var formattedwaterQuantity = waterQuantity.toString().substring(0, 4);\n return formattedwaterQuantity;\n }\n\n function hasZones() {\n var retVal = false;\n if ($scope.flight && $scope.flight.Zones && $scope.flight.Zones.length > 0) retVal = true;\n return retVal;\n }\n\n function getZone(classService) {\n var retVal = '';\n var zone;\n\n if ($scope.flight && $scope.flight.Zones) {\n // zone = $scope.flight.Zones.find(function (item) {\n // return item.Class == classService || item.Class == '';\n // });\n for (var i = 0; i < $scope.flight.Zones.length; i++) {\n if ($scope.flight.Zones[i].Class == classService || $scope.flight.Zones[i].Class == '') {\n zone = $scope.flight.Zones[i];\n break;\n }\n }\n }\n\n if (zone) retVal = zone.Title;\n return retVal;\n }\n\n function detailedInfo(properties) {\n var propertiesArray = properties.split(',');\n var htmlPopover = '';\n\n if ($scope.paxInfo && $scope.paxInfo.PassengerSummaryC && $scope.paxInfo.PassengerSummaryY) {\n if (propertiesArray.length > 1) {\n htmlPopover = '
C
Y
Total
';\n angular.forEach(propertiesArray, function (property) {\n var Total = $scope.paxInfo.PassengerSummaryC['Total' + property] + $scope.paxInfo.PassengerSummaryY['Total' + property];\n\n if (Total > 0) {\n var code = '';\n\n for (var i = 0; i < ssrCodes.length; i++) {\n if (ssrCodes[i].code == property) {\n code = ssrCodes[i].description;\n }\n }\n\n htmlPopover = htmlPopover + '
' + property + \"\";\n htmlPopover = htmlPopover + '' + code + \"\";\n htmlPopover = htmlPopover + '
' + $scope.paxInfo.PassengerSummaryC[property] + \"
\";\n htmlPopover = htmlPopover + '
' + $scope.paxInfo.PassengerSummaryY[property] + \"
\";\n htmlPopover = htmlPopover + '
' + Total + \"
\";\n }\n });\n } else {\n angular.forEach(propertiesArray, function (property) {\n var Total = $scope.paxInfo.PassengerSummaryC['Total' + property] + $scope.paxInfo.PassengerSummaryY['Total' + property];\n htmlPopover = '
C ' + $scope.paxInfo.PassengerSummaryC[property] + '';\n htmlPopover = htmlPopover + ' Y ' + $scope.paxInfo.PassengerSummaryY[property] + '';\n\n if (Total) {\n htmlPopover = htmlPopover + ' Total ' + Total + '';\n }\n\n htmlPopover = htmlPopover + '
';\n });\n }\n }\n\n return $sce.trustAsHtml(htmlPopover);\n }\n }\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('updateConfirm', updateConfirm);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name updateConfirm\r\n * @restrict E\r\n * @description\r\n * Implementation of aircraft differences\r\n *\r\n * Display the confirm textto update service workers version\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function updateConfirm(SWUpdateService) {\n function link($scope, element, attributes) {\n //if serviceWorker registered\n if ($scope.SWRegistration != null) {\n $scope.needUpdate = null;\n $scope.update = update; //get waiting service worker if exists\n\n $scope.needUpdate = $scope.SWRegistration.waiting; //if waiting service woker exists check how long its been waiting\n\n if ($scope.needUpdate != null) {\n SWUpdateService.checkVersionExpiration($scope.SWRegistration);\n }\n }\n\n function update() {\n SWUpdateService.update($scope.SWRegistration);\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/directives/updateConfirm.tpl.html',\n scope: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n// array functions\nArray.prototype.dynamicSort = function (property, orderByAsc) {\n function dynamicSortComparator(property, orderByAsc) {\n var sortOrder = orderByAsc ? 1 : -1;\n return function (a, b) {\n var result = a[property] < b[property] ? -1 : a[property] > b[property] ? 1 : 0;\n return result * sortOrder;\n };\n }\n\n var sortedArray = this;\n\n if (property != null && property != undefined) {\n orderByAsc = orderByAsc == null || orderByAsc == undefined ? true : orderByAsc;\n sortedArray = this.sort(dynamicSortComparator(property, orderByAsc));\n }\n\n return sortedArray;\n};\n\nArray.prototype.unique = function () {\n var arr = [];\n\n for (var i = 0; i < this.length; i++) {\n if (!arr.contains(this[i])) {\n arr.push(this[i]);\n }\n }\n\n return arr;\n};\n\nArray.prototype.contains = function (v) {\n for (var i = 0; i < this.length; i++) {\n if (this[i] === v) return true;\n }\n\n return false;\n};\n\nArray.prototype.groupByKey = function (key) {\n return this.reduce(function (rv, x) {\n (rv[x[key]] = rv[x[key]] || []).push(x);\n return rv;\n }, {});\n};\n\"use strict\";\n\n// date functions\nDate.prototype.toUTC = function () {\n return new Date(this.getTime() + this.getTimezoneOffset() * 60 * 1000);\n};\n\nDate.prototype.fromUTC = function () {\n return new Date(this.getTime() - this.getTimezoneOffset() * 60 * 1000);\n};\n\nDate.prototype.trimTime = function () {\n this.setHours(0, 0, 0, 0);\n return this;\n};\n\nvar _DatetoJSON = Date.prototype.toJSON;\n\nDate.prototype.toJSON = function () {\n try {\n return _DatetoJSON.call(this);\n } catch (e) {\n if (e instanceof RangeError) {\n return null;\n }\n\n throw e;\n }\n};\n\nDate.DifferenceInMinutes = function (firstDate, secondDate) {\n var diffInMins = null;\n\n if (firstDate && secondDate) {\n var _MS_TO_MINUTES = 1000 * 60;\n\n var date1 = new Date(firstDate);\n var date2 = new Date(secondDate);\n diffInMins = Math.floor((date2.getTime() - date1.getTime()) / _MS_TO_MINUTES);\n }\n\n return diffInMins;\n};\n\nDate.DifferenceInDays = function (firstDate, secondDate) {\n var diffInDays = null;\n\n if (firstDate && secondDate) {\n var _MS_TO_DAYS = 1000 * 3600 * 24;\n\n diffInDays = Math.floor((secondDate.getTime() - firstDate.getTime()) / _MS_TO_DAYS);\n }\n\n return diffInDays;\n};\n\nDate.MinutesToString = function (minutes) {\n var hours = Math.floor(minutes / 60);\n var mins = minutes % 60;\n return (hours > 0 ? hours + (hours == 1 ? \"hr \" : \"hrs \") : \"\") + (mins > 0 ? mins + (mins == 1 ? \"min\" : \"mins\") : \"\");\n};\n\nDate.prototype.AddDays = function (days) {\n var date = new Date(this.valueOf());\n date.setDate(date.getDate() + days);\n return date;\n};\n\nDate.MinutesToStringSimple = function (minutes) {\n var hours = Math.floor(minutes / 60);\n var mins = minutes % 60;\n return (hours != 0 ? hours + \":\" : \"00\" + \":\") + (mins > 9 ? mins : \"0\" + mins);\n};\n\"use strict\";\n\n// generic string functions\nString.prototype.endsWith = function (suffix) {\n return this.indexOf(suffix, this.length - suffix.length) !== -1;\n};\n\nif (typeof String.prototype.startsWith != 'function') {\n // see below for better implementation!\n String.prototype.startsWith = function (str) {\n return this.indexOf(str) == 0;\n };\n}\n\nString.prototype.reverse = function () {\n return this.split(\"\").reverse().join(\"\");\n};\n\nString.prototype.getHash = function () {\n var shaObj = new jsSHA(\"SHA-512\", \"TEXT\");\n shaObj.update(this);\n var hash = shaObj.getHash(\"HEX\");\n return hash;\n};\n\nString.prototype.elipsis = function (charNo) {\n return this.length > charNo ? this.substring(0, charNo) + \"...\" : this;\n};\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('faceMasks', faceMasks);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name faceMasks\r\n * @restrict E\r\n * @description\r\n * Implementation of Face Masks \r\n *\r\n * Display the Face Masks Record Panel\r\n * @attr {String} flight-id\r\n * @example\r\n * Usage:\r\n * \r\n * \r\n * @ngInject\r\n */\n\n function faceMasks(FlightFactory, FaceMasksFactory, $sce, $timeout) {\n /**\r\n * Initialize faceMasks\r\n * @memberof faceMasks\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\n function link(scope, element, attributes) {\n scope.togglePanel = togglePanel;\n scope.submit = submit;\n scope.numberDown = numberDown;\n scope.numberUp = numberUp;\n scope.validInput = validInput;\n scope.validateForm = validateForm;\n scope.requiredFields = false;\n scope.invalidForm = false;\n scope.LastUpdated = null;\n initializePanel();\n /**\r\n * Initialize Form Values\r\n * @memberof faceMasks\r\n */\n\n function initializePanel() {\n var flight = FlightFactory.getFlightFromStorage(scope.flightId);\n var DryStoreFound = 0;\n var DryStoreLeft = 0;\n var UniversalFound = 0;\n var UniversalLeft = 0; //Check if there is existing data\n\n if (flight.FaceMasks) {\n DryStoreFound = flight.FaceMasks.DryStoreFound;\n DryStoreLeft = flight.FaceMasks.DryStoreLeft;\n UniversalFound = flight.FaceMasks.UniversalFound;\n UniversalLeft = flight.FaceMasks.UniversalLeft;\n scope.LastUpdated = flight.FaceMasks.LastUpdated;\n }\n\n var masksForm = {\n Types: [{\n Type: \"A\",\n Title: \"FFP2 Masks\",\n Fields: [{\n Title: \"Found\",\n Value: DryStoreFound\n }, {\n Title: \"Left\",\n Value: DryStoreLeft\n }]\n }, {\n Type: \"B\",\n Title: \"Surgical Face masks\",\n Fields: [{\n Title: \"Found\",\n Value: UniversalFound\n }, {\n Title: \"Left\",\n Value: UniversalLeft\n }]\n }],\n FlightId: scope.flightId\n };\n scope.submitMessage = '';\n scope.masksForm = masksForm;\n scope.showPanel = \"masks\";\n validateForm();\n }\n /**\r\n * Check if all required fields exist and have a valid value\r\n * @memberof faceMasks\r\n */\n\n\n function validateForm() {\n scope.requiredFields = scope.masksForm.Types.some(function (t) {\n return t.Fields.some(function (f) {\n return f.Value === null;\n });\n });\n scope.invalidForm = scope.masksForm.Types.some(function (t) {\n return t.Fields.some(function (f) {\n return f.Value === undefined;\n });\n }); //Hide other alerts when form is invalid\n\n if (scope.requiredFields || scope.invalidForm) {\n scope.showPanel = \"masks\";\n }\n }\n /**\r\n * Toggle Panel\r\n * @memberof faceMasks\r\n * @param {number} panelId\r\n */\n\n\n function togglePanel(panelId) {\n $('#' + panelId).toggle();\n }\n\n function validInput(field) {\n var isValid = true;\n\n if (field.Value == null || field.Value == undefined) {\n isValid = false;\n }\n\n return isValid;\n }\n /**\r\n * Decrease field value by 1\r\n * @memberof faceMasks\r\n * @param {object} field \r\n */\n\n\n function numberDown(field) {\n if (field.Value > 0) {\n field.Value--;\n }\n }\n /**\r\n * Increase field value by 1\r\n * @memberof faceMasks\r\n * @param {object} field \r\n */\n\n\n function numberUp(field) {\n field.Value++;\n }\n /**\r\n * Submit form\r\n * @memberof faceMasks\r\n */\n\n\n function submit() {\n if (scope.isOffline) {\n scope.showPanel = \"offline\";\n } else {\n scope.showPanel = \"loading\";\n var DryStoreFound = scope.masksForm.Types.find(function (t) {\n return t.Type == \"A\";\n }).Fields.find(function (f) {\n return f.Title == \"Found\";\n }).Value;\n var DryStoreLeft = scope.masksForm.Types.find(function (t) {\n return t.Type == \"A\";\n }).Fields.find(function (f) {\n return f.Title == \"Left\";\n }).Value;\n var UniversalFound = scope.masksForm.Types.find(function (t) {\n return t.Type == \"B\";\n }).Fields.find(function (f) {\n return f.Title == \"Found\";\n }).Value;\n var UniversalLeft = scope.masksForm.Types.find(function (t) {\n return t.Type == \"B\";\n }).Fields.find(function (f) {\n return f.Title == \"Left\";\n }).Value;\n var FlightMaskReport = {\n FlightId: scope.masksForm.FlightId,\n DryStoreFound: DryStoreFound,\n DryStoreLeft: DryStoreLeft,\n UniversalFound: UniversalFound,\n UniversalLeft: UniversalLeft,\n LastUpdated: new Date()\n };\n FaceMasksFactory.submitFaceMaskReport(FlightMaskReport).then(function (res) {\n return handleSubmitResponse(res, FlightMaskReport.LastUpdated);\n });\n }\n }\n /**\r\n * Manage API response\r\n * @param {object} res \r\n * @param {date} timestamp \r\n */\n\n\n function handleSubmitResponse(res, timestamp) {\n if (res.success) {\n manageResponseMessage(\"success\", res.message);\n scope.LastUpdated = timestamp;\n $timeout(function () {\n scope.showPanel = \"masks\";\n }, 6000);\n } else {\n manageResponseMessage(\"failure\", res.message);\n }\n }\n /**\r\n * Manage message alerts\r\n * @param {string} panelToShow \r\n * @param {string} message \r\n */\n\n\n function manageResponseMessage(panelToShow, message) {\n scope.submitMessage = message;\n scope.showPanel = panelToShow;\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/FaceMasks/faceMasks.tpl.html',\n scope: {\n flightId: '@',\n isOffline: '='\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('FaceMasksFactory', FaceMasksFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FaceMasksFactory\r\n * @description \r\n * Get, Set and Submit Face Mask Info per flight.\r\n * @ngInject\r\n */\n\n function FaceMasksFactory(FlightFactory, $http, apiUrl) {\n var submitResponseObj = {\n success: false,\n message: ''\n };\n var service = {\n submitFaceMaskReport: submitFaceMaskReport\n };\n /**\r\n * Sends the Face Masks report\r\n * @memberof FaceMasksFactory\r\n * @param {object} flightMasks The Flight Face Masks Report\r\n * @returns {promise} submitResponseObj\r\n */\n\n function submitFaceMaskReport(flightMasks) {\n var objectToAdd = flightMasks;\n return $http.post(apiUrl + '/FaceMasks/', flightMasks, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return saveReportSuccessCallBack(res, objectToAdd);\n })[\"catch\"](function (res) {\n return saveReportFailedCallBack(res);\n });\n }\n /**\r\n * The callback function upon successful submit\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} submitResponseObj\r\n */\n\n\n function saveReportSuccessCallBack(res, objectToAdd) {\n submitResponseObj.success = res.data.success;\n\n if (res.data.success) {\n //Attach face mask info to flight\n var flight = FlightFactory.getFlightFromStorage(objectToAdd.FlightId);\n flight.FaceMasks = objectToAdd;\n FlightFactory.updateFlight(flight);\n submitResponseObj.message = \"Success! Your input has been sent\";\n } else {\n submitResponseObj.message = res.data.errorMessage;\n }\n\n return submitResponseObj;\n }\n /**\r\n * The callback function upon failure on submit\r\n * @returns {object} submitResponseObj\r\n */\n\n\n function saveReportFailedCallBack(res) {\n submitResponseObj.success = false;\n submitResponseObj.message = \"Oops! Something went wrong\";\n return submitResponseObj;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('FaqFactory', FaqFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FaqFactory\r\n * @description \r\n * Add, Update, Delete and Get FAQ.\r\n * @ngInject\r\n */\n\n function FaqFactory(GenericService) {\n /**\r\n * Initialize the FAQ\r\n * @memberof FaqFactory\r\n */\n function FAQ() {\n this.Id = null;\n this.FAQCategory = null;\n this.FAQSubcategory = null;\n this.Question = null;\n this.Answer = null;\n this.IsNew = null; //if FAQ is brand new\n\n this.WasUpdated = null; //if FAQ was updated\n }\n\n var objType = 'FAQItem';\n var objCallback = FAQ;\n var service = {\n getFAQsFromStorage: getFAQsFromStorage,\n setFAQsToStorage: setFAQsToStorage,\n setFAQsFromServer: setFAQsFromServer\n };\n /**\r\n * Get FAQs\r\n * @memberof FaqFactory\r\n * @returns {Array} faqs \r\n */\n\n function getFAQsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Set FAQs\r\n * @memberof FaqFactory\r\n * @param {array} FAQItem \r\n */\n\n\n function setFAQsToStorage(FAQItem) {\n GenericService.saveAll(FAQItem, objType, objCallback);\n }\n /**\r\n * Delete FAQs\r\n * @memberof FaqFactory\r\n */\n\n\n function clearFAQsFromStorage() {\n GenericService.removeAll(objType, objCallback);\n }\n /**\r\n * Set FAQs from api data\r\n * @memberof FaqFactory\r\n * @param {array} FAQItem \r\n */\n\n\n function setFAQsFromServer(newFAQs) {\n var oldFAQs = getFAQsFromStorage();\n\n if (oldFAQs.length > 0) {\n var newPairList = [];\n var oldPairList = []; //make a list with all new FAQ Question-Answer pair\n\n for (var i = 0; i < newFAQs.length; i++) {\n for (var j = 0; j < newFAQs[i].Subcategories.length; j++) {\n for (var k = 0; k < newFAQs[i].Subcategories[j].Pairs.length; k++) {\n newPairList.push(newFAQs[i].Subcategories[j].Pairs[k]);\n }\n\n ;\n }\n\n ;\n }\n\n ; //make a list with all old FAQ Question-Answer pair\n\n for (var i = 0; i < oldFAQs.length; i++) {\n for (var j = 0; j < oldFAQs[i].Subcategories.length; j++) {\n for (var k = 0; k < oldFAQs[i].Subcategories[j].Pairs.length; k++) {\n oldPairList.push(oldFAQs[i].Subcategories[j].Pairs[k]);\n }\n\n ;\n }\n\n ;\n }\n\n ; //iterate both lists and check if there are new or updated items\n\n for (var i = 0; i < newPairList.length; i++) {\n var exists = false;\n\n for (var j = 0; j < oldPairList.length; j++) {\n if (newPairList[i].Id == oldPairList[j].Id && newPairList[i].LastUpdated != oldPairList[j].LastUpdated) {\n newPairList[i].WasUpdated = true;\n exists = true;\n break;\n }\n\n if (newPairList[i].Id == oldPairList[j].Id) {\n exists = true;\n break;\n }\n }\n\n if (!exists) {\n newPairList[i].IsNew = true;\n }\n } //enter updated list to FAQ Object\n\n\n for (var i = 0; i < newFAQs.length; i++) {\n newFAQs[i].updatedItems = 0;\n newFAQs[i].newItems = 0;\n\n for (var j = 0; j < newFAQs[i].Subcategories.length; j++) {\n for (var k = 0; k < newFAQs[i].Subcategories[j].Pairs.length; k++) {\n for (var l = 0; l < newPairList.length; l++) {\n if (newFAQs[i].Subcategories[j].Pairs[k].Id == newPairList[l].Id) {\n newFAQs[i].Subcategories[j].Pairs[k] = newPairList[l];\n\n if (newPairList[l].IsNew) {\n newFAQs[i].newItems++;\n }\n\n if (newPairList[l].WasUpdated) {\n newFAQs[i].updatedItems++;\n }\n\n break;\n }\n }\n\n ;\n }\n\n ;\n }\n\n ;\n }\n\n ;\n setFAQsToStorage(newFAQs);\n } else {\n setFAQsToStorage(newFAQs);\n }\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('FaqsCtrl', FaqsCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FaqsCtrl\r\n * @description \r\n * Shows Faqs\r\n * @ngInject\r\n */\n\n function FaqsCtrl($scope, FaqFactory, $uibModal, $route) {\n var FAQs = FaqFactory.getFAQsFromStorage();\n $scope.state = 'faqs';\n $scope.newFAQCount = 0;\n $scope.updatedFAQCount = 0;\n $scope.openAnswer = openAnswer;\n $scope.FAQItems = FAQs;\n $scope.updateFAQs = updateFAQs;\n $scope.searchText = '';\n $scope.btnFilter = '';\n\n for (var i = 0; i < FAQs.length; i++) {\n if (FAQs[i].newItems) {\n $scope.newFAQCount += FAQs[i].newItems;\n }\n\n if (FAQs[i].updatedItems) {\n $scope.updatedFAQCount += FAQs[i].updatedItems;\n }\n }\n /**\r\n * Open selected FAQ\r\n * @memberof FaqsCtrl \r\n * @param {object} pair The FAQ\r\n */\n\n\n function openAnswer(_pair) {\n var modalInstance = $uibModal.open({\n templateUrl: './views/Dialogs/dlgOpenAnswer.html',\n controller: 'FaqsModalCtrl',\n size: 'lg',\n resolve: {\n pair: function pair() {\n return _pair;\n }\n }\n });\n modalInstance.result.then(function () {\n //FAQ is no longer New or Updated\n if (_pair.IsNew || _pair.WasUpdated) {\n for (var i = 0; i < FAQs.length; i++) {\n for (var j = 0; j < FAQs[i].Subcategories.length; j++) {\n for (var k = 0; k < FAQs[i].Subcategories[j].Pairs.length; k++) {\n if (FAQs[i].Subcategories[j].Pairs[k].Id == _pair.Id) {\n if (FAQs[i].Subcategories[j].Pairs[k].IsNew) {\n FAQs[i].Subcategories[j].Pairs[k].IsNew = false;\n FAQs[i].newItems--;\n }\n\n if (FAQs[i].Subcategories[j].Pairs[k].WasUpdated) {\n FAQs[i].Subcategories[j].Pairs[k].WasUpdated = false;\n FAQs[i].updatedItems--;\n }\n }\n }\n }\n }\n\n FaqFactory.setFAQsToStorage(FAQs);\n $route.reload();\n }\n }, function () {});\n }\n /**\r\n * Filter FAQs\r\n * @memberof FaqsCtrl \r\n * @param {string} searchText The search text\r\n * @param {string} btnFilter New, updated or all\r\n */\n\n\n function updateFAQs(searchText, btnFilter) {\n var oldFAQs = FAQs;\n var FAQ = [];\n searchText = searchText.toLowerCase();\n\n for (var i = 0; i < oldFAQs.length; i++) {\n var Category = {};\n Category.Subcategories = [];\n var showCategory = false;\n\n for (var j = 0; j < oldFAQs[i].Subcategories.length; j++) {\n var Subcategory = {};\n Subcategory.Pairs = [];\n var showSubCategory = false;\n\n for (var k = 0; k < oldFAQs[i].Subcategories[j].Pairs.length; k++) {\n var question = oldFAQs[i].Subcategories[j].Pairs[k].Question.toLowerCase();\n var answer = oldFAQs[i].Subcategories[j].Pairs[k].Answer.toLowerCase();\n\n if ((question.indexOf(searchText) > -1 || answer.indexOf(searchText) > -1) && (!btnFilter || btnFilter == 'new' && oldFAQs[i].Subcategories[j].Pairs[k].IsNew || btnFilter == 'updated' && oldFAQs[i].Subcategories[j].Pairs[k].WasUpdated)) {\n showCategory = true;\n showSubCategory = true;\n Subcategory.Pairs.push(oldFAQs[i].Subcategories[j].Pairs[k]);\n }\n }\n\n if (showSubCategory) {\n Subcategory.SubcategoryDescription = oldFAQs[i].Subcategories[j].SubcategoryDescription;\n Category.Subcategories.push(Subcategory);\n }\n }\n\n if (showCategory) {\n Category.CategoryDescription = oldFAQs[i].CategoryDescription;\n FAQ.push(Category);\n }\n }\n\n $scope.FAQItems = FAQ;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('FaqsModalCtrl', FaqsModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FaqsModalCtrl\r\n * @description \r\n * Shows an FAQ \r\n * @ngInject\r\n */\n\n function FaqsModalCtrl($scope, $uibModalInstance, pair) {\n $scope.pair = pair;\n $scope.cancel = cancel;\n /**\r\n * Close the modal\r\n * @memberof FaqsModalCtrl\r\n */\n\n function cancel() {\n $uibModalInstance.close('close');\n }\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('aimsCrewMemos', aimsCrewMemos);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name aimsCrewMemos\r\n * @restrict E\r\n * @description\r\n * Implementation of aimsCrewMemos\r\n * Initialize the Aims Crew Memos\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function aimsCrewMemos(AimsCrewMemosFactory) {\n function link($scope, element, attrs) {\n $scope.aimsCrewMemos = AimsCrewMemosFactory.getAimsCrewMemosByDate(attrs.date);\n }\n\n return {\n restrict: 'E',\n templateUrl: \"views/directives/aimsCrewMemos.tpl.html\",\n scope: true,\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('AimsCrewMemosFactory', AimsCrewMemosFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AimsCrewMemosFactory\r\n * @description \r\n * Add, Update, Delete and Get Aims Crew Memos.\r\n * @ngInject\r\n */\n\n function AimsCrewMemosFactory(GenericService) {\n /**\r\n * Initialize the AircaftPositions\r\n * @memberof AircaftPositionsFactory\r\n */\n function AimsCrewMemos() {\n this.Date = null;\n this.Line = null;\n this.OrderNo = null;\n this.GetId = GetId;\n }\n\n var objType = 'AimsCrewMemos';\n var objCallback = AimsCrewMemos;\n var service = {\n getAimsCrewMemosFromStorage: getAimsCrewMemosFromStorage,\n setAimsCrewMemosToStorage: setAimsCrewMemosToStorage,\n clearAimsCrewMemosFactoryFromStorage: clearAimsCrewMemosFactoryFromStorage,\n getAimsCrewMemosByDate: getAimsCrewMemosByDate,\n upsertAimsCrewMemos: upsertAimsCrewMemos,\n cleanOldAimsCrewMemos: cleanOldAimsCrewMemos\n };\n /**\r\n * Overide default get Id\r\n * @memberof AimsCrewMemosFactory\r\n * @returns {string} Id \r\n */\n\n function GetId() {\n return this.Date;\n }\n /**\r\n * Get Aims Crew Memos\r\n * @memberof AimsCrewMemosFactory\r\n * @returns {Array} Aims Crew Memos\r\n */\n\n\n function getAimsCrewMemosFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save Aims Crew Memos to storage\r\n * @memberof AimsCrewMemosFactory\r\n * @param {Array} A list of Aims Crew Memos\r\n */\n\n\n function setAimsCrewMemosToStorage(aircaftPositions) {\n GenericService.saveAll(aircaftPositions, objType, objCallback);\n }\n /**\r\n * Remove the Aims Crew Memos of the local storage\r\n * @memberof AimsCrewMemosFactory\r\n */\n\n\n function clearAimsCrewMemosFactoryFromStorage() {\n GenericService.removeAll(objType, objCallback);\n }\n /**\r\n * Get AimsCrewMemosFactory of this flight by date\r\n * @memberof AimsCrewMemosFactory\r\n * @returns {Object} AimsCrewMemosFactory\r\n */\n\n\n function getAimsCrewMemosByDate(date) {\n var crewMemos = getAimsCrewMemosFromStorage();\n var datesMemos = [];\n var arrayLength = crewMemos.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (crewMemos[i].GetId() == date) {\n datesMemos.push(crewMemos[i]);\n }\n }\n\n return datesMemos;\n }\n /**\r\n * Upsert Aims Crew Memos\r\n * @memberof AimsCrewMemosFactory\r\n */\n\n\n function upsertAimsCrewMemos(aimsCrewMemos) {\n var newCrewMemos = aimsCrewMemos.map(function (x) {\n return x.Date;\n });\n var aimsCrewMemosLS = this.getAimsCrewMemosFromStorage();\n aimsCrewMemosLS = aimsCrewMemosLS.filter(function (x) {\n return !newCrewMemos.includes(x.Date);\n });\n var allAimsCrewMemos = aimsCrewMemosLS.concat(aimsCrewMemos);\n setAimsCrewMemosToStorage(allAimsCrewMemos);\n }\n /**\r\n * Clean Old Data\r\n * @memberof AimsCrewMemosFactory\r\n */\n\n\n function cleanOldAimsCrewMemos() {\n var now = moment();\n getAimsCrewMemosFromStorage(function (crewMemos) {\n var memosToKeep = crewMemos.filter(function (item) {\n var memoDate = moment(item.Date);\n return now.diff(memoDate, 'days') < 5;\n }); // keep only the memo with pending reports\n\n setAimsCrewMemosToStorage(memosToKeep);\n });\n } // var dutyDate = moment(cabinReportLocalEdits[i].DutyDate);\n // if (cabinReportLocalEdits[i].Status !== 'stored' && now.diff(dutyDate, 'days') < 5) {\n\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('AircaftPositionsFactory', AircaftPositionsFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AircaftPositionsFactory\r\n * @description \r\n * Add, Update, Delete and Get AircaftPositions.\r\n * @ngInject\r\n */\n\n function AircaftPositionsFactory(GenericService) {\n /**\r\n * Initialize the AircaftPositions\r\n * @memberof AircaftPositionsFactory\r\n */\n function AircaftPositions() {\n this.FlightId = null;\n this.PreviousFlightNo = null;\n this.PreviousStation = null;\n this.PreviousSTA = null;\n this.PreviousETA = null;\n this.PreviousATA = null;\n this.PreviousGATE = null;\n this.PreviousSTAND = \"\";\n this.PreviousSTANDArrival = \"\";\n this.NextFlightNo = null;\n this.NextStation = null;\n this.NextSTD = null;\n this.NextETD = null;\n this.NextATD = null;\n this.NextGATE = null;\n this.NextSTAND = \"\";\n this.NextSTANDArrival = \"\";\n this.GetId = GetId;\n }\n\n var objType = 'aircaftpositions';\n var objCallback = AircaftPositions;\n var service = {\n getAircaftPositionsFromStorage: getAircaftPositionsFromStorage,\n setAircaftPositionsToStorage: setAircaftPositionsToStorage,\n clearAircaftPositionsFromStorage: clearAircaftPositionsFromStorage,\n getAircaftPositionsByFlightId: getAircaftPositionsByFlightId,\n updateAircraftPositionsToStorage: updateAircraftPositionsToStorage,\n cleanOldData: cleanOldData\n };\n /**\r\n * Overide default get Id\r\n * @memberof AircaftPositionsFactory\r\n * @returns {number} Id \r\n */\n\n function GetId() {\n return this.FlightId;\n }\n /**\r\n * Get messages\r\n * @memberof AircaftPositionsFactory\r\n * @returns {Array} Aircaft Positions \r\n */\n\n\n function getAircaftPositionsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save Aircaft Positions to storage\r\n * @memberof AircaftPositionsFactory\r\n * @param {Array} messages A list of Aircaft Positions\r\n */\n\n\n function setAircaftPositionsToStorage(aircaftPositions) {\n GenericService.saveAll(aircaftPositions, objType, objCallback);\n }\n /**\r\n * Remove the Aircaft Positions of the local storage\r\n * @memberof AircaftPositionsFactory\r\n */\n\n\n function clearAircaftPositionsFromStorage() {\n GenericService.removeAll(objType, objCallback);\n }\n /**\r\n * Get Aircaft Positions of this flight\r\n * @memberof AircaftPositionsFactory\r\n * @returns {Object} Aircaft Positions \r\n */\n\n\n function getAircaftPositionsByFlightId(flightId) {\n return GenericService.get(flightId, objType, objCallback);\n }\n /**\r\n * Update Aircraft Position to storage\r\n * @memberof AircaftPositionsFactory\r\n * @param {object} aircraftPositions Aircraft Positions\r\n */\n\n\n function updateAircraftPositionsToStorage(aircraftPositions, flightId) {\n if (GenericService.get(flightId, objType, objCallback)) {\n GenericService.save(aircraftPositions, objType, objCallback);\n } else if (aircraftPositions != null) GenericService.add(aircraftPositions, objType, objCallback);\n }\n /**\r\n * Clean ls from old flights aircraft positions\r\n * @param {array} flights Synced flights\r\n */\n\n\n function cleanOldData(responseFlightIds) {\n var previousAircaftPositions = getAircaftPositionsFromStorage();\n previousAircaftPositions = previousAircaftPositions.filter(function (x) {\n return responseFlightIds.includes(x.FlightId);\n });\n setAircaftPositionsToStorage(previousAircaftPositions);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('AircraftDifferencesFactory', AircraftDifferencesFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AircraftDifferencesFactory\r\n * @description \r\n * Add, Update, Delete and Get AircraftDifferences.\r\n * @ngInject\r\n */\n\n function AircraftDifferencesFactory(GenericService, FlightFactory) {\n /**\r\n * Initialize the AircraftPositions\r\n * @memberof AircraftDifferencesFactory\r\n */\n function AircraftDifferences() {\n this.GetId = GetId;\n }\n\n var objType = 'AircraftDifferences';\n var objCallback = AircraftDifferences;\n var service = {\n getAircraftDifferencesFromStorage: getAircraftDifferencesFromStorage,\n setAircraftDifferencesToStorage: setAircraftDifferencesToStorage,\n clearAircraftDifferencesFromStorage: clearAircraftDifferencesFromStorage,\n getAircraftDifferencesByFlightId: getAircraftDifferencesByFlightId,\n getAircraftDifferenceFromStorageByRegistration: getAircraftDifferenceFromStorageByRegistration,\n upsertAircraftDifferences: upsertAircraftDifferences\n };\n /**\r\n * Override default get Id\r\n * @memberof AircraftDifferencesFactory\r\n * @returns {number} Id \r\n */\n\n function GetId() {\n return this.Registration;\n }\n /**\r\n * Get messages\r\n * @memberof AircraftDifferencesFactory\r\n * @returns {Array} Aircraft Differences \r\n */\n\n\n function getAircraftDifferencesFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n\n function getAircraftDifferenceFromStorageByRegistration(registration) {\n return GenericService.get(registration, objType, objCallback);\n }\n /**\r\n * Save Aircraft Differences to storage\r\n * @memberof AircraftDifferencesFactory\r\n * @param {Array} messages A list of Aircraft Differences\r\n */\n\n\n function setAircraftDifferencesToStorage(aircraftDifferences) {\n GenericService.saveAll(aircraftDifferences, objType, objCallback);\n }\n /**\r\n * Remove the Aircraft Differences of the local storage\r\n * @memberof AircraftDifferencesFactory\r\n */\n\n\n function clearAircraftDifferencesFromStorage() {\n GenericService.removeAll(objType, objCallback);\n }\n /**\r\n * Get Aircraft Differences of this flight\r\n * @memberof AircraftDifferencesFactory\r\n * @returns {Object} Aircraft Differences \r\n */\n\n\n function getAircraftDifferencesByFlightId(flightId) {\n var retVal = [];\n var flight = FlightFactory.getFlightFromStorage(flightId);\n\n if (!flight) {\n flight = FlightFactory.getLocalFlightFromStorage(flightId);\n }\n\n if (!flight) {\n return [];\n }\n\n var difference = getAircraftDifferenceFromStorageByRegistration(flight.AcTailNo);\n retVal = difference != null && difference.AircraftDifferences != null ? difference.AircraftDifferences : [];\n return retVal; // return GenericService.get(flightId,objType,objCallback);\n }\n /**\r\n * Upsert aircraft differences\r\n * @memberof AircraftDifferencesFactory\r\n */\n\n\n function upsertAircraftDifferences(aircraftDifferences) {\n var newAircraftDifferences = aircraftDifferences.map(function (x) {\n return x.Registration;\n });\n var aircraftDifferencesLS = this.getAircraftDifferencesFromStorage();\n aircraftDifferencesLS = aircraftDifferencesLS.filter(function (x) {\n return !newAircraftDifferences.includes(x.Registration);\n });\n var updatedAircraftDifferences = aircraftDifferencesLS.concat(aircraftDifferences);\n setAircraftDifferencesToStorage(updatedAircraftDifferences);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('crewRouteInfoPanel', crewRouteInfoPanel);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name crewRouteInfoPanel\r\n * @restrict EA\r\n * @description\r\n * Implementation of crewRouteInfoPanel\r\n *\r\n * Initialize the crew Route Info panel \r\n * @example\r\n * Usage:\r\n *
or \r\n * @ngInject\r\n */\n\n function crewRouteInfoPanel($routeParams, $uibModal) {\n function link($scope, element, attrs) {\n $scope.showDefaultView = showDefaultView;\n $scope.showFlightTimes = showFlightTimes;\n $scope.showCommercialView = showCommercialView;\n $scope.showDelaysView = showDelaysView;\n $scope.showHiddenRows = false;\n $scope.toggleshowHiddenRows = toggleshowHiddenRows;\n $scope.defaultColumns = true;\n $scope.commercialColumns = false;\n $scope.timesColumns = false;\n $scope.delaysColumns = false;\n $scope.crewMeals = '';\n $scope.showDate = showDate;\n $scope.openCrewContactsModal = openCrewContactsModal;\n\n function showDefaultView() {\n $scope.defaultColumns = true;\n $scope.timesColumns = false;\n $scope.commercialColumns = false;\n $scope.delaysColumns = false;\n }\n\n function showFlightTimes() {\n $scope.defaultColumns = false;\n $scope.timesColumns = true;\n $scope.commercialColumns = false;\n $scope.delaysColumns = false;\n }\n\n function showCommercialView() {\n $scope.defaultColumns = false;\n $scope.timesColumns = false;\n $scope.commercialColumns = true;\n $scope.delaysColumns = false;\n }\n\n function showDelaysView() {\n $scope.defaultColumns = false;\n $scope.timesColumns = false;\n $scope.commercialColumns = false;\n $scope.delaysColumns = true;\n }\n\n function toggleshowHiddenRows() {\n if ($scope.crewRouteInfoPanel.hasAircraftPositions) {\n $scope.showHiddenRows = !$scope.showHiddenRows;\n }\n }\n\n function showDate(acRouteSTD, flightSTD) {\n var datediff = moment(acRouteSTD).startOf('day').diff(moment(flightSTD).startOf('day'), 'days');\n return datediff != 0;\n }\n /**\r\n * Open dialog with the crew details\r\n * @memberof BucketCtrl\r\n */\n\n\n function openCrewContactsModal(_crewInfo, _selectedflightid, _selectedFlightNo) {\n if (_crewInfo && _crewInfo.length > 0) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/CrewRoute/dlgCrewContacts.html',\n controller: 'CrewContactsModalCtrl',\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n crewInfo: function crewInfo() {\n return _crewInfo;\n },\n selectedflightid: function selectedflightid() {\n return _selectedflightid;\n },\n selectedFlightNo: function selectedFlightNo() {\n return _selectedFlightNo;\n }\n }\n });\n }\n }\n }\n\n return {\n restrict: 'EA',\n terminal: true,\n templateUrl: 'views/directives/crewRouteInfoPanel.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('FlightConfigCtrl', FlightConfigCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FlightConfigCtrl\r\n * @description \r\n * Set the ETA of the flight\r\n * @ngInject\r\n */\n\n function FlightConfigCtrl($scope, $uibModalInstance, flight, FlightFactory) {\n $scope.cancel = cancel;\n $scope.save = save;\n $scope.flightETA = new Date(flight.ETA ? flight.ETA : flight.ScheduledArrival);\n /**\r\n * Save the new ETA\r\n * @memberof FlightConfigCtrl\r\n */\n\n function save() {\n if ($scope.flightETA) {\n var ETAdate = $scope.flightETA;\n var STDdate = new Date(flight.ScheduledDeparture);\n var ETAtimestamp = ETAdate.getTime();\n var STDtimestamp = STDdate.getTime();\n ETAdate.setUTCFullYear(STDdate.getUTCFullYear());\n ETAdate.setUTCMonth(STDdate.getUTCMonth());\n ETAdate.setUTCDate(STDdate.getUTCDate());\n\n if (ETAtimestamp < STDtimestamp) {\n ETAdate.setUTCDate(STDdate.getUTCDate() + 1);\n }\n\n $scope.flightETA = ETAdate;\n }\n\n flight.ETA = $scope.flightETA;\n FlightFactory.updateFlight(flight);\n $uibModalInstance.close(flight);\n }\n /**\r\n * Close the modal\r\n * @memberof FlightConfigCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.dismiss();\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('FlightDelaysFactory', FlightDelaysFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightDelaysFactory\r\n * @description \r\n * Add, Update, Delete and Get FlightDelays.\r\n * @ngInject\r\n */\n\n function FlightDelaysFactory(GenericService) {\n var objType = 'FlightDelays';\n var objCallback = FlightDelays;\n /**\r\n * Initialize the FlightDelays\r\n * @memberof FlightDelaysFactory\r\n */\n\n function FlightDelays() {\n this.GetId = GetId;\n }\n\n var service = {\n getFlightDelaysFromStorage: getFlightDelaysFromStorage,\n setFlightDelaysToStorage: setFlightDelaysToStorage,\n getFlightDelaysByFlightId: getFlightDelaysByFlightId,\n addFlightDelays: addFlightDelays,\n upsertFlightDelays: upsertFlightDelays,\n cleanOldFlightDelays: cleanOldFlightDelays\n }; //Object Functions\n\n /**\r\n * Overide default get Id\r\n * @memberof FlightFactory\r\n * @returns {number} Id \r\n */\n\n function GetId() {\n return this.FlightId;\n }\n /**\r\n * Get FlightDelays\r\n * @memberof FlightDelaysFactory\r\n * @param {function} callback \r\n */\n\n\n function getFlightDelaysFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n\n ;\n /**\r\n * Save FlightDelays to storage\r\n * @memberof FlightDelaysFactory\r\n * @param {Array} FlightDelays A list of FlightDelays\r\n */\n\n function setFlightDelaysToStorage(flightDelays) {\n GenericService.saveAll(flightDelays, objType, objCallback);\n }\n /**\r\n * Get single flight FlightDelays\r\n * @memberof FlightDelaysFactory\r\n * @param {function} callback \r\n */\n\n\n function getFlightDelaysByFlightId(flightId) {\n return GenericService.get(flightId, objType, objCallback);\n }\n\n ;\n /**\r\n * Set single flight FlightDelays\r\n * @memberof FlightDelaysFactory\r\n * @param {function} callback \r\n */\n\n function addFlightDelays(FlightDelays) {\n return GenericService.add(FlightDelays, objType, objCallback);\n }\n\n ;\n /**\r\n * Upsert Flight Delays\r\n * @memberof FlightDelaysFactory\r\n */\n\n function upsertFlightDelays(newflightDelays) {\n var newFLightIds = newflightDelays.map(function (x) {\n return x.FlightId;\n });\n var flightDelaysLS = this.getFlightDelaysFromStorage();\n flightDelaysLS = flightDelaysLS.filter(function (x) {\n return !newFLightIds.includes(x.FlightId);\n });\n var allFlightDelays = flightDelaysLS.concat(newflightDelays);\n setFlightDelaysToStorage(allFlightDelays);\n }\n /**\r\n * Clean Old Data\r\n * @memberof FlightDelaysFactory\r\n * @param {Array} pendingFlightIds FlightIds with pending reports\r\n */\n\n\n function cleanOldFlightDelays(pendingFlightIds) {\n var now = moment();\n getFlightDelaysFromStorage(function (flightDelays) {\n var pendingFlightDelays = flightDelays.filter(function (item) {\n var date = moment(item.FlightDate);\n return pendingFlightIds.includes(item.FlightId) || now.diff(date, 'days') < 5;\n }); // keep only the FlightDelays with pending reports\n\n setFlightDelaysToStorage(pendingFlightDelays);\n });\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('FlightGateCtrl', FlightGateCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FlightGateCtrl\r\n * @description \r\n * View all flight connections and search for more possible connecting flights\r\n * @ngInject\r\n */\n\n function FlightGateCtrl($scope, $uibModalInstance, flight, FlightGateFactory, SyncLogFactory, FlightFactory, PaxInfoFactory) {\n var flightId = flight.FlightId;\n var items = [];\n var syncLog = SyncLogFactory.getSyncLog();\n var distinct_gates = [];\n var searchFilters = flight.FlightsFilters;\n var gates = FlightGateFactory.getAfterSTDFromStorage(flight.ScheduledDeparture, flight.Arrival);\n $scope.isConnectedFlightClose = isConnectedFlightClose;\n $scope.TimeDifference = TimeDifference;\n $scope.IsOld = IsOld;\n $scope.searchText = '';\n $scope.addFilter = addFilter;\n $scope.removeFilter = removeFilter;\n $scope.cancel = cancel;\n $scope.filters = searchFilters;\n PaxInfoFactory.getPaxInfoFromStorage(flight.FlightId, function (paxInfo) {\n if (paxInfo) {\n items = paxInfo.TotalFlights;\n $scope.items = items.sort(function (a, b) {\n return new Date(a.STD).getTime() - new Date(b.STD).getTime();\n });\n\n for (var i = 0; i < gates.length; i++) {\n var exists = false;\n\n for (var j = 0; j < items.length; j++) {\n if (items[j].FlightNo == gates[i].FlightNo && items[j].Dep == gates[i].Dep) {\n var connectingTime = new Date(items[j].STD_lcl);\n var flightGateTime = new Date(gates[i].STD);\n\n if (connectingTime.getTime() == flightGateTime.getTime()) {\n if (!items[j].Codeshares || items[j].Codeshares.length == 0) {\n items[j].Codeshares == gates[i].Codeshares;\n }\n\n exists = true;\n break;\n }\n }\n }\n\n if (!exists) {\n var distinct_gate = {\n FlightNo: gates[i].FlightNo,\n Gate: gates[i].DepGate,\n Arr: gates[i].Arrival,\n STD_lcl: gates[i].STD_lcl,\n STD: gates[i].STD,\n pax: null,\n Codeshares: gates[i].Codeshares,\n UpdatedDate: gates[i].lastUpdate\n };\n distinct_gates.push(distinct_gate);\n }\n }\n }\n });\n var flightArrivalTime = new Date(flight.ScheduledArrival).getTime();\n $scope.hasGates = distinct_gates.length > 0;\n $scope.flightETA = flight.ETA ? new Date(flight.ETA).getTime() : flightArrivalTime;\n applyFilter();\n /**\r\n * Calculates if a connecting flight is departs sort time after fligths arrival \r\n * @memberof FlightGateCtrl\r\n * @param {string} connection Connection STD\r\n * @return {string} cssClass\r\n */\n\n function isConnectedFlightClose(connection) {\n if (!connection) {\n return '';\n }\n\n var connFlightDate = new Date(connection).getTime();\n if ($scope.flightETA > connFlightDate) return '';\n\n if (connFlightDate - $scope.flightETA < 3600001) {\n return 'bg-bisque';\n }\n\n if (connFlightDate - $scope.flightETA < 6480000) {\n return 'bg-cornsilk';\n }\n\n return '';\n }\n /**\r\n * Returns the time difference\r\n * @memberof FlightGateCtrl\r\n * @param {string} time Connection STD\r\n * @return {string} timeDifference\r\n */\n\n\n function TimeDifference(time) {\n var timeString = '';\n var sign = '';\n var dayString = null;\n\n if (time) {\n var connFlightDate = new Date(time);\n var ms = connFlightDate.getTime() - $scope.flightETA; // this is a time in milliseconds\n\n if (ms < 0) {\n ms = -ms;\n sign = \"-\";\n }\n\n var days = Math.floor(ms / (24 * 60 * 60 * 1000));\n days = days < 0 ? days + 1 : days;\n var daysms = ms % (24 * 60 * 60 * 1000);\n var hours = Math.floor(daysms / (60 * 60 * 1000));\n var hoursms = ms % (60 * 60 * 1000);\n var minutes = Math.floor(hoursms / (60 * 1000));\n timeString = '' + sign + (hours > 0 ? (\"0\" + hours).substr(-2) + \":\" : '') + (\"0\" + minutes).substr(-2) + '\\'' + '';\n dayString = ' ' + days + 'd';\n }\n\n return timeString + (days && days != 0 ? dayString : '');\n }\n /**\r\n * Checks if the data are new\r\n * @memberof FlightGateCtrl\r\n * @param {string} time timestamp\r\n * @return {boolean} IsOld\r\n */\n\n\n function IsOld(time) {\n IsOld = false;\n\n if (time) {\n var now = new Date();\n var timeDate = new Date(time);\n var diff = now.getTime() - timeDate.getTime();\n\n if (diff > 3600000) {\n IsOld = true;\n }\n }\n\n return IsOld;\n }\n /**\r\n * Apply given filters to show connectings flights\r\n * @memberof FlightGateCtrl\r\n */\n\n\n function applyFilter() {\n var newFlightgates = [];\n\n if (searchFilters.length > 0) {\n for (var i = 0; i < distinct_gates.length; i++) {\n for (var j = 0; j < searchFilters.length; j++) {\n var row = distinct_gates[i].FlightNo + \",\" + distinct_gates[i].Codeshares.toString();\n\n if (row.indexOf(searchFilters[j].toString()) >= 0) {\n newFlightgates.push(distinct_gates[i]);\n break;\n }\n }\n }\n }\n\n $scope.gates = newFlightgates.sort(function (a, b) {\n return new Date(a.STD).getTime() - new Date(b.STD).getTime();\n });\n }\n /**\r\n * Add a filter\r\n * @memberof FlightGateCtrl\r\n * @param {string} searchText Search text\r\n */\n\n\n function addFilter(searchText) {\n if (searchText.trim().length > 0) {\n var exists = false;\n\n for (var i = 0; i < $scope.filters.length; i++) {\n if ($scope.filters[i] == searchText.toString().toUpperCase()) {\n exists = true;\n break;\n }\n }\n\n if (!exists) {\n var flight = FlightFactory.getFlightFromStorage(flightId);\n searchFilters.push(searchText.toString().toUpperCase());\n flight.FlightsFilters = searchFilters;\n FlightFactory.updateFlight(flight);\n $scope.filters = searchFilters;\n }\n\n $scope.searchText = \"\";\n applyFilter();\n }\n }\n /**\r\n * Remove a filter\r\n * @memberof FlightGateCtrl\r\n * @param {item} string filter\r\n */\n\n\n function removeFilter(item) {\n var flight = FlightFactory.getFlightFromStorage(flightId);\n var index = searchFilters.indexOf(item);\n searchFilters.splice(index, 1);\n flight.FlightsFilters = searchFilters;\n FlightFactory.updateFlight(flight);\n $scope.filters = searchFilters;\n applyFilter();\n }\n /**\r\n * Close the modal\r\n * @memberof FlightGateCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close($scope.gates);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('FlightGateFactory', FlightGateFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightGateFactory\r\n * @description \r\n * Add, Update, Delete and Get Flight Gates.\r\n * @ngInject\r\n */\n\n function FlightGateFactory(GenericService) {\n /**\r\n * Initialize the FlightGate\r\n * @memberof FlightGateFactory\r\n */\n function FlightGate() {\n this.FlightDate = null;\n this.Codeshares = [];\n this.FlightNo = null;\n this.Departure = null;\n this.Arrival = null;\n this.STD = null;\n this.STA = null;\n this.ETD = null;\n this.ETA = null;\n this.STD_Diff = null;\n this.STA_Diff = null;\n this.STD_lcl = null;\n this.STA_lcl = null;\n this.ETD_lcl = null;\n this.ETA_lcl = null;\n this.DepGate = null;\n this.DepStand = null;\n this.AcType = null;\n this.lastUpdate = null; //net fields used to hold values before latest update\n\n this.previousUpdate = null;\n this.previousGate = null;\n this.previousSTD = null;\n this.previousSTD_lcl = null;\n this.previousSTD_Diff = null;\n this.previousSTA = null;\n this.previousSTA_lcl = null;\n this.previousSTA_Diff = null; //object functions\n\n this.getRoute = getRoute;\n this.dtSTD = dtSTD;\n this.dtSTA = dtSTA;\n this.dtETD = dtETD;\n this.dtETA = dtETA;\n this.dtSTD_lcl = dtSTD_lcl;\n this.dtSTA_lcl = dtSTA_lcl;\n this.dtETD_lcl = dtETD_lcl;\n this.dtETA_lcl = dtETA_lcl;\n this.dateSTD = dateSTD;\n this.timeSTD = timeSTD;\n this.timeSTA = timeSTA;\n this.timeETD = timeETD;\n this.timeETA = timeETA;\n this.timeSTD_lcl = timeSTD_lcl;\n this.timeSTA_lcl = timeSTA_lcl;\n this.timeETD_lcl = timeETD_lcl;\n this.timeETA_lcl = timeETA_lcl;\n this.hasETD = hasETD;\n this.hasETA = hasETA;\n this.depDelay = depDelay;\n this.arrDelay = arrDelay;\n this.setUpdatedNow = setUpdatedNow;\n this.gateChanged = gateChanged;\n this.stdChanged = stdChanged;\n this.staChanged = staChanged;\n this.stdDiffChanged = stdDiffChanged;\n this.staDiffChanged = staDiffChanged;\n this.toString = toString;\n this.changesToString = changesToString;\n this.getKey = getKey;\n }\n\n var objType = 'FlightGates';\n var objCallback = FlightGate;\n var service = {\n processUpdatedData: processUpdatedData,\n getFromStorage: getFromStorage,\n getAfterSTDFromStorage: getAfterSTDFromStorage,\n setToStorage: setToStorage\n }; //Object functions\n\n function getRoute() {\n if (this.Departure == null && this.Arrival == null) return '-null-';else return (this.Departure || '?') + '-' + (this.Arrival || '?');\n }\n /**\r\n * Transform STD iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\n\n\n function dtSTD() {\n return stringIsoToDateTime(this.STD);\n }\n /**\r\n * Transform STA iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\n\n\n function dtSTA() {\n return stringIsoToDateTime(this.STA);\n }\n /**\r\n * Transform ETD iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\n\n\n function dtETD() {\n return stringIsoToDateTime(this.ETD);\n }\n /**\r\n * Transform ETA iso string to date\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\n\n\n function dtETA() {\n return stringIsoToDateTime(this.ETA);\n }\n /**\r\n * Transform local STD iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\n\n\n function dtSTD_lcl() {\n return stringIsoToDateTime(this.STD_lcl);\n }\n /**\r\n * Transform local STA iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\n\n\n function dtSTA_lcl() {\n return stringIsoToDateTime(this.STA_lcl);\n }\n /**\r\n * Transform local ETD iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\n\n\n function dtETD_lcl() {\n return stringIsoToDateTime(this.ETD_lcl);\n }\n /**\r\n * Transform local ETA iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\n\n\n function dtETA_lcl() {\n return stringIsoToDateTime(this.ETA_lcl);\n }\n /**\r\n * Transform STD iso string to date string\r\n * @memberof FlightGateFactory\r\n * @return {string} date\r\n */\n\n\n function dateSTD() {\n return stringIsoToDateString(this.STD);\n }\n /**\r\n * Transform STD iso string to time string \r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\n\n\n function timeSTD() {\n return stringIsoToTimeString(this.STD);\n }\n /**\r\n * Transform STA iso string to time string \r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\n\n\n function timeSTA() {\n return stringIsoToTimeString(this.STA);\n }\n /**\r\n * Transform ETD iso string to time string\r\n * @memberof FlightGateFactory\r\n * @return {object} time\r\n */\n\n\n function timeETD() {\n return stringIsoToTimeString(this.ETD);\n }\n /**\r\n * Transform ETA iso string to time string\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\n\n\n function timeETA() {\n return stringIsoToTimeString(this.ETA);\n }\n /**\r\n * Transform STD iso string to local time string\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\n\n\n function timeSTD_lcl() {\n return stringIsoToTimeString(this.STD_lcl);\n }\n /**\r\n * Transform local STA iso string to string time\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\n\n\n function timeSTA_lcl() {\n return stringIsoToTimeString(this.STA_lcl);\n }\n /**\r\n * Transform local ETD iso string to time string\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\n\n\n function timeETD_lcl() {\n return stringIsoToTimeString(this.ETD_lcl);\n }\n /**\r\n * Transform local ETA iso string to time\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\n\n\n function timeETA_lcl() {\n return stringIsoToTimeString(this.ETA_lcl);\n }\n /**\r\n * check if gate has ETD\r\n * @memberof FlightGateFactory\r\n * @return {boolean} hasETD\r\n */\n\n\n function hasETD() {\n if (this.ETD && this.STD != this.ETD && this.dtSTD() < this.dtETD()) return true;else return false;\n }\n /**\r\n * check if gate has ETA\r\n * @memberof FlightGateFactory\r\n * @return {boolean} hasETA\r\n */\n\n\n function hasETA() {\n return this.ETA && this.STA != this.ETA && this.dtSTA() < this.dtETA();\n }\n /**\r\n * Return departure delay\r\n * @memberof FlightGateFactory\r\n * @return {string} STD_Diff\r\n */\n\n\n function depDelay() {\n if (this.hasETD() && this.STD_Diff && this.STD_Diff > 0) return this.STD_Diff;else return null;\n }\n /**\r\n * Return arrival delay\r\n * @memberof FlightGateFactory\r\n * @return {boolean} STA_Diff\r\n */\n\n\n function arrDelay() {\n if (this.hasETA() && this.STA_Diff && this.STA_Diff > 0) return this.STA_Diff;else return null;\n }\n /**\r\n * record the current time as the lastUpdate of the object\r\n * @memberof FlightGateFactory\r\n */\n\n\n function setUpdatedNow() {\n this.lastUpdate = new Date();\n if (this.DepGate == null) this.DepGate = '';\n }\n /**\r\n * Check if the gate has changed since the last update\r\n * @memberof FlightGateFactory\r\n * @return {boolean} gateChanged\r\n */\n\n\n function gateChanged() {\n if (!this.previousGate) return false;else return true;\n }\n /**\r\n * Check if the STD has changed since the last update\r\n * @memberof FlightGateFactory\r\n * @return {boolean} stdChanged\r\n */\n\n\n function stdChanged() {\n if (!this.previousSTD) return false;else return true;\n }\n /**\r\n * Check if the STA has changed since the last update\r\n * @memberof FlightGateFactory\r\n * @return {boolean} staChanged\r\n */\n\n\n function staChanged() {\n if (!this.previousSTA) return false;else return true;\n }\n /**\r\n * Check if the STD diff has changed since the last update\r\n * @memberof FlightGateFactory\r\n * @return {boolean} stdDiffChanged\r\n */\n\n\n function stdDiffChanged() {\n if (!this.previousSTD_Diff) return false;else return true;\n }\n /**\r\n * Check if the STA diff has changed since the last update\r\n * @memberof FlightGateFactory\r\n * @return {boolean} staDiffChanged\r\n */\n\n\n function staDiffChanged() {\n if (!this.previousSTA_Diff) return false;else return true;\n }\n /**\r\n * Print the flight gate info\r\n * @memberof FlightGateFactory\r\n * @return {string} toSting\r\n */\n\n\n function toString() {\n var s = this.dateSTD() + ' ' + this.FlightNo;\n s += ' ' + this.Departure + '-' + this.Arrival;\n s += ' ' + (this.hasETD() ? 'ETD' + this.timeETD_lcl() + (this.depDelay() ? '[+' + this.depDelay() + '\\']' : '') : 'STD' + this.timeSTD_lcl());\n s += '->' + (this.hasETA() ? 'ETA' + this.timeETA_lcl() + '[' + (this.STA_Diff > 0 ? '+' : '-') + this.STA_Diff + '\\']' : 'STA' + this.timeSTA_lcl());\n s += this.DepGate ? ' Gate: ' + this.DepGate : '';\n return s;\n }\n /**\r\n * Show all the changes of the flight gates\r\n * @memberof FlightGateFactory\r\n * @return {string} toSting\r\n */\n\n\n function changesToString() {\n var s = '';\n if (this.stdChanged()) s += 'STD: ' + stringIsoToTimeString(this.previousSTD) + ' -> ' + this.timeSTD();\n if (self.stdDiffChanged()) s += (s == '' ? '' : ', ') + 'departure delay: ' + this.previousSTD_Diff + ' -> ' + this.STD_Diff;\n if (self.staChanged()) s += (s == '' ? '' : ', ') + 'STA: ' + stringIsoToTimeString(this.previousSTA) + ' -> ' + this.timeSTA();\n if (self.staDiffChanged()) s += (s == '' ? '' : ', ') + 'arrival delay: ' + this.previousSTA_Diff + ' -> ' + this.STA_Diff;\n if (self.gateChanged()) s += (s == '' ? '' : ', ') + ' gate: ' + this.previousGate + ' -> ' + this.DepGate;\n return s;\n }\n /**\r\n * returns a string with all the fields uniquely defining a flight, concatenated\r\n * @memberof FlightGateFactory\r\n * @return {string} key\r\n */\n\n\n function getKey() {\n var s = this.FlightDate + '|' + this.FlightNo + '|' + this.Departure + '-' + this.Arrival;\n return s;\n } //Service functions\n\n /**\r\n * Transform iso datetime string to date time Object\r\n * @memberof FlightGateFactory\r\n * @return {Object} DateTime\r\n */\n\n\n function stringIsoToDateTime(str) {\n var dt = null;\n\n try {\n if (str) {\n //replace T in order to avoid browser converting datetime to browser's timezone\n //eg 2016-05-17T23:04:00 would be converted to Wed May 18 2016 02:04:00 GMT+0300 (GTB Daylight Time) when we want it to be Tue May 17 2016 23:04:00 GMT+0300 (GTB Daylight Time)\n str = str.replace('T', ' ');\n dt = new Date(str);\n }\n } catch (e) {}\n\n return dt;\n }\n /**\r\n * Transform iso datetime string to date string\r\n * @memberof FlightGateFactory\r\n * @return {string} date\r\n */\n\n\n function stringIsoToDateString(str) {\n var dt = stringIsoToDateTime(str);\n var s = null;\n\n if (dt) {\n var year = dt.getFullYear();\n var month = dt.getMonth() + 1;\n var day = dt.getDate();\n s = (day < 10 ? '0' : '') + day + '.' + (month < 10 ? '0' : '') + month + '.' + year;\n }\n\n return s;\n }\n /**\r\n * Transform iso datetime string to time string\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\n\n\n function stringIsoToTimeString(str) {\n var dt = stringIsoToDateTime(str);\n var s = null;\n\n if (dt) {\n var hour = dt.getHours();\n var min = dt.getMinutes();\n s = (hour < 10 ? '0' : '') + hour + ':' + (min < 10 ? '0' : '') + min + '';\n }\n\n return s;\n }\n /**\r\n * Process updated list of fligths 'gates' and store them.Before storing them, we need to identify changes in Gates and in ETD/ETA to notify customers when required. \r\n * @memberof FlightGateFactory\r\n */\n\n\n function processUpdatedData(data) {\n //Update List\n var list = fromObjectList(data); //Original List\n\n var listPrevious = getFromStorage(); //Search each \"new\" flight in the new list, and check if it has been modified since last update\n\n if (list && list.length > 0) {\n var flight, flightPrevious, hasChanged;\n var previousLength = listPrevious.length;\n\n for (var i = 0; i < list.length; i++) {\n flight = list[i]; //mark that this flight was updated now\n\n flight.setUpdatedNow(); //check for flight in previous list, and if found, check for changes\n\n if (listPrevious && previousLength > 0) {\n for (var p = 0; p < previousLength; p++) {\n flightPrevious = listPrevious[p];\n\n if (flight.getKey() === flightPrevious.getKey()) {\n hasChanged = false;\n\n if (flight.DepGate != flightPrevious.DepGate) {\n hasChanged = true;\n flight.previousGate = flightPrevious.DepGate;\n }\n\n if (flight.STD != flightPrevious.STD) {\n hasChanged = true;\n flight.previousSTD = flightPrevious.STD;\n flight.previousSTD_lcl = flightPrevious.STD_lcl;\n }\n\n if (flight.STA != flightPrevious.STA) {\n hasChanged = true;\n flight.previousSTA = flightPrevious.STA;\n flight.previousSTA_lcl = flightPrevious.STA_lcl;\n }\n\n if (flight.STD_Diff != flightPrevious.STD_Diff) {\n hasChanged = true;\n flight.previousSTD_Diff = flightPrevious.STD_Diff;\n }\n\n if (flight.STA_Diff != flightPrevious.STA_Diff) {\n hasChanged = true;\n flight.previousSTA_Diff = flightPrevious.STA_Diff;\n }\n\n if (hasChanged) {\n flight.previousUpdate = flightPrevious.lastUpdate;\n }\n\n break;\n }\n }\n }\n }\n }\n\n setToStorage(list);\n }\n /**\r\n * Get flightgates from storage\r\n * @memberof FlightGateFactory\r\n * @return {array} flightgates\r\n */\n\n\n function getFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Get flightgates after std and flight gates selected departure\r\n * @memberof FlightGateFactory\r\n * @param {string} std STD iso datetime string \r\n * @param {string} dep Departure\r\n * @return {array} flightgates\r\n */\n\n\n function getAfterSTDFromStorage(std, dep) {\n var newFlightgates = [];\n var now_utc = new Date(std);\n var date = now_utc.getTime();\n var flightgates = getFromStorage();\n\n for (var i = 0; i < flightgates.length; i++) {\n var dateSTD = new Date(flightgates[i].STD);\n var dateETD = null;\n\n if (dateETD) {\n dateETD = new Date(flightgates[i].ETD);\n }\n\n if ((dateSTD.getTime() >= date || dateETD != null && dateETD.getTime() >= date) && dep == flightgates[i].Departure && //check only for 2 days later\n dateSTD.getTime() <= date + 172800000) {\n newFlightgates.push(flightgates[i]);\n }\n }\n\n return newFlightgates;\n }\n /**\r\n * Set flightgates from storage\r\n * @memberof FlightGateFactory\r\n * @param {array} data\r\n */\n\n\n function setToStorage(data) {\n GenericService.saveAll(data, objType, objCallback);\n }\n /**\r\n * Extend an array of Objects from the default FlightGate Object\r\n * @memberof FlightGateFactory\r\n * @param {Array} objList an Array Of FlightGates\r\n * @returns {Array} FlightGates\r\n */\n\n\n function fromObjectList(objList) {\n if (!objList) return [];\n var arrayLength = objList.length;\n var result = [];\n\n for (var i = 0; i < arrayLength; i++) {\n var item = new FlightGate();\n angular.extend(item, objList[i]);\n result.push(item);\n }\n\n return result;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('FlightInfoCtrl', FlightInfoCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FlightInfoCtrl\r\n * @description \r\n * Shows the flight informations\r\n * @ngInject\r\n */\n\n function FlightInfoCtrl($scope, FlightFactory, MessageFactory, $routeParams, AircaftPositionsFactory, CrewCallFactory, PreviousDutyFactory, $location, $uibModal, PaxInfoFactory, CampaignFactory, UserFactory, barOptions, $anchorScroll, enableFaceMasks, FlightCheckInsFactory, CrewRouteFactory) {\n var flightId = $routeParams.flightId;\n var flight = FlightFactory.getFlightFromTotalFlights(flightId);\n var crewPhoneNumbers = CrewCallFactory.getFlightCrewCallsFromStorage(flightId);\n var previousDuties = PreviousDutyFactory.getFlightPreviousDutiesFromStorage(flightId);\n $scope.user = UserFactory.getUser();\n $scope.flightId = flightId;\n $scope.shownSideMenu = false;\n $scope.sideMenuItems = [];\n $scope.showSidePanel = showSidePanel;\n $scope.hideSidePanel = hideSidePanel;\n $scope.goToPanel = goToPanel;\n $scope.isMobile = window.innerWidth <= 800 && window.innerHeight <= 740;\n $scope.campaigns = CampaignFactory.getCampaignsByFlightId(+flightId); // function detectMobile() {\n // $scope.isMobile =(window.innerWidth <= 800 && window.innerHeight <= 740); \n // console.log($scope.isMobile);\n // return $scope.isMobile;\t\t\n // }\t\n\n function hideSidePanel() {\n $scope.shownSideMenu = false;\n }\n\n function goToPanel(id) {\n $location.hash(id);\n $anchorScroll();\n hideSidePanel();\n }\n\n ;\n\n function showSidePanel() {\n $scope.sideMenuItems = [];\n $('.panel-heading .title').each(function () {\n var menuItem = {};\n menuItem.id = $(this).attr(\"id\");\n menuItem.title = $(this).html();\n menuItem.icon = $(this).data('icon');\n $scope.sideMenuItems.push(menuItem);\n });\n $scope.shownSideMenu = true;\n }\n\n if (!flight) {\n // go to dashboard if no flight\n $location.path(\"/\");\n } else {\n //Initialize Zones\n var onlyUnique = function onlyUnique(value, index, self) {\n return self.indexOf(value) === index;\n };\n\n var RenderFlightZones = function RenderFlightZones(zones) {\n if (!zones) return;\n var flightZones = [];\n var zoneTitles = zones.map(function (item) {\n return item.Title;\n });\n var uniqueZones = zoneTitles.filter(onlyUnique); // //or\n // var uniqueZones2 = Array.from(new Set(zoneTitles));\n\n uniqueZones.forEach(function (element) {\n var getZoneCounter = zoneTitles.filter(function (item) {\n return item == element;\n });\n\n if (getZoneCounter.length > 1) {\n flightZones.push({\n Title: element.Title,\n Class: null\n });\n } else {\n var zone = zones.filter(function (item) {\n return item.Title == element;\n });\n flightZones.push(zone[0]);\n }\n });\n return flightZones;\n }; //Initialize Messages\n\n\n //Controllers Functions\n //TODO : find a more angular way (EPAP)\n\n /**\r\n * toggle View Mode\r\n * @memberof FlightInfoCtrl\r\n * @param {string} elem\r\n * @param {string} className \r\n */\n var toggleViewMode = function toggleViewMode(elem, className) {\n $('body').find('div#' + elem + ' > div').not('.tip').hide(\"slow\");\n $('body').find('div#' + elem + ' div.' + className).not('.tip').show(\"slow\");\n }; //TODO : find a more angular way (EPAP)\n\n /**\r\n * toggle Panel\r\n * @memberof FlightInfoCtrl\r\n * @param {number} panelId\r\n */\n\n\n var togglePanel = function togglePanel(panelId) {\n $('#' + panelId).toggle();\n if (panelId == \"info-panel\") $scope.isPanelOpen = !$scope.isPanelOpen;\n };\n /**\r\n * Open modal to see information for the selected message\r\n * @memberof FlightInfoCtrl\r\n * @param {object} message A message object\r\n */\n\n\n var openMessage = function openMessage(_message) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgMessage.html',\n controller: 'MessageModalCtrl',\n size: 'lg',\n keyboard: false,\n backdrop: \"static\",\n resolve: {\n message: function message() {\n return _message;\n }\n }\n });\n modalInstance.result.then(function () {\n if (_message.ReadDt == null) {\n MessageFactory.markReaden(_message.Id);\n _message.ReadDt = new Date();\n }\n });\n };\n /**\r\n * Open modal to see information for gates and connections\r\n * @memberof FlightInfoCtrl\r\n */\n\n\n var openGates = function openGates() {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgFlightGates.html',\n controller: 'FlightGateCtrl',\n size: 'lg',\n resolve: {\n flight: function flight() {\n return $scope.flight;\n }\n }\n });\n modalInstance.result.then(function (selectedItem) {\n $scope.gates = selectedItem;\n });\n };\n /**\r\n * Return the text ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\n\n\n var getTextClass = function getTextClass() {\n var classname = \"\";\n if (flight.LineStatus === 'na') classname = \"text-gray\";else if (flight.LineStatus === 'pending') classname = \"text-blue\";else if (flight.LineStatus === 'pendingoverdue') classname = \"text-blue\";else if (flight.LineStatus === 'draft' || flight.LineStatus === 'draftotheruser') {\n classname = \"text-orange\";\n } else if (flight.LineStatus === 'completed' || flight.LineStatus === 'completedotheruser') {\n classname = \"text-purple\";\n } else if (flight.LineStatus === 'stored' || flight.LineStatus === 'storedotheruser' || flight.LineStatus === 'stored+otheruser' || flight.LineStatus === 'synched' || flight.LineStatus === 'synchedotheruser') {\n classname = \"text-green\";\n }\n return classname;\n };\n /**\r\n * Return the panel upper ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\n\n\n var getTopClass = function getTopClass() {\n var classname = \"\";\n if (flight.LineStatus === 'na') classname = \"border-top-gray\";else if (flight.LineStatus === 'pending') classname = \"border-top-blue\";else if (flight.LineStatus === 'pendingoverdue') classname = \"border-top-blue\";else if (flight.LineStatus === 'draft' || flight.LineStatus === 'draftotheruser') {\n classname = \"border-top-orange\";\n } else if (flight.LineStatus === 'completed' || flight.LineStatus === 'completedotheruser') {\n classname = \"border-top-purple\";\n } else if (flight.LineStatus === 'stored' || flight.LineStatus === 'storedotheruser' || flight.LineStatus === 'stored+otheruser' || flight.LineStatus === 'synched' || flight.LineStatus === 'synchedotheruser') {\n classname = \"border-top-green\";\n }\n return classname;\n };\n /**\r\n * Return the panel border ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\n\n\n var getBottomClass = function getBottomClass() {\n var classname = \"\";\n if (flight.LineStatus === 'na') classname = \"border-bottom-gray\";else if (flight.LineStatus === 'pending') classname = \"border-bottom-blue\";else if (flight.LineStatus === 'pendingoverdue') classname = \"border-bottom-blue\";else if (flight.LineStatus === 'draft' || flight.LineStatus === 'draftotheruser') {\n classname = \"border-bottom-orange\";\n } else if (flight.LineStatus === 'completed' || flight.LineStatus === 'completedotheruser') {\n classname = \"border-bottom-purple\";\n } else if (flight.LineStatus === 'stored' || flight.LineStatus === 'storedotheruser' || flight.LineStatus === 'stored+otheruser' || flight.LineStatus === 'synched' || flight.LineStatus === 'synchedotheruser') {\n classname = \"border-bottom-green\";\n }\n return classname;\n };\n /**\r\n * If report from another user exists, show icon\r\n * @memberof FlightInfoCtrl\r\n * @returns {boolean} hasIcon\r\n */\n\n\n var hasIcon = function hasIcon() {\n var hasIcon = false;\n\n if (flight.LineStatus === 'draftotheruser' || flight.LineStatus === 'completedotheruser' || flight.LineStatus === 'storedotheruser' || flight.LineStatus === 'stored+otheruser' || flight.LineStatus === 'synchedotheruser') {\n hasIcon = true;\n }\n\n return hasIcon;\n };\n /**\r\n * Checks if the data are new\r\n * @memberof FlightInfoCtrl\r\n * @param {string} time timestamp\r\n * @return {boolean} IsOld\r\n */\n\n\n var _IsOld = function IsOld(time) {\n _IsOld = false;\n\n if (time) {\n var now = new Date();\n var timeDate = new Date(time);\n var diff = now.getTime() - timeDate.getTime();\n\n if (diff > 3600000) {\n _IsOld = true;\n }\n }\n\n return _IsOld;\n };\n /**\r\n * Calculates if a connecting flight is departs sort time after fligths arrival \r\n * @memberof FlightInfoCtrl\r\n * @param {string} connection Connection STD\r\n * @return {string} cssClass\r\n */\n\n\n var isConnectedFlightClose = function isConnectedFlightClose(connection) {\n if (!connection) {\n return '';\n }\n\n var connFlightDate = new Date(connection.STD).getTime();\n if ($scope.flightETA > connFlightDate) return '';\n\n if (connFlightDate - $scope.flightETA < connection.MCT * 60000) {\n return 'bg-bisque';\n }\n\n if (connFlightDate - $scope.flightETA < (connection.MCT + 15) * 60000) {\n return 'bg-cornsilk';\n }\n\n return '';\n };\n /**\r\n * Returns the time difference\r\n * @memberof FlightInfoCtrl\r\n * @param {string} time Connection STD\r\n * @return {string} timeDifference\r\n */\n\n\n var TimeDifference = function TimeDifference(time) {\n var timeString = '';\n var sign = '';\n var dayString = null;\n\n if (time) {\n var connFlightDate = new Date(time);\n var ms = connFlightDate.getTime() - $scope.flightETA; // this is a time in milliseconds\n\n if (ms < 0) {\n ms = -ms;\n sign = \"-\";\n }\n\n var days = Math.floor(ms / (24 * 60 * 60 * 1000));\n days = days < 0 ? days + 1 : days;\n var daysms = ms % (24 * 60 * 60 * 1000);\n var hours = Math.floor(daysms / (60 * 60 * 1000));\n var hoursms = ms % (60 * 60 * 1000);\n var minutes = Math.floor(hoursms / (60 * 1000));\n timeString = '' + sign + (hours > 0 ? (\"0\" + hours).substr(-2) + \":\" : '') + (\"0\" + minutes).substr(-2) + '\\'' + '';\n dayString = ' ' + days + 'd';\n }\n\n return timeString + (days && days != 0 ? dayString : '');\n };\n /**\r\n * Open Flight config modal\r\n * @memberof FlightInfoCtrl\r\n */\n\n\n var openFlightConfig = function openFlightConfig() {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgFlightConfig.html',\n controller: 'FlightConfigCtrl',\n size: 'md',\n resolve: {\n flight: function flight() {\n return $scope.flight;\n }\n }\n });\n modalInstance.result.then(function (selectedItem) {\n $scope.flightETA = new Date(selectedItem.ETA).getTime();\n $scope.flight = selectedItem;\n });\n };\n /**\r\n * Returns the assessment Text Class\r\n * @memberof FlightInfoCtrl\r\n * @return {string} classname\r\n */\n\n\n var getAssessmentTextClass = function getAssessmentTextClass() {\n var classname = \"\";\n\n if (flight.assessment) {\n if (flight.assessment.IsExist) {\n classname = \"text-green\";\n } else if (flight.assessment.Status === 'Pending') classname = \"text-blue\";else if (flight.assessment.Status === 'Draft') {\n classname = \"text-orange\";\n } else if (flight.assessment.Status === 'Completed') {\n classname = \"text-purple\";\n } else if (flight.assessment.Status === 'Stored') {\n classname = \"text-green\";\n }\n }\n\n return classname;\n };\n /**\r\n * Returns the crew Chart\r\n * @memberof FlightInfoCtrl\r\n * @param {object} flight The flight object\r\n * @return {object} crewChart\r\n */\n\n\n var generateCrewChart = function generateCrewChart(flight) {\n var cp = 0;\n var fo = 0;\n var sa = 0;\n var fa = 0;\n var dhcCp = 0;\n var dhcFo = 0;\n var dhcSa = 0;\n var dhcFa = 0;\n\n if (flight.crew) {\n for (var i = 0; i < flight.crew.length; i++) {\n if (flight.crew[i].isDHC) {\n switch (flight.crew[i].position) {\n case \"CP\":\n dhcCp++;\n break;\n\n case \"FO\":\n dhcFo++;\n break;\n\n case \"SA\":\n dhcSa++;\n break;\n\n case \"FA\":\n dhcFa++;\n break;\n }\n } else {\n switch (flight.crew[i].position) {\n case \"CP\":\n cp++;\n break;\n\n case \"FO\":\n fo++;\n break;\n\n case \"SA\":\n sa++;\n break;\n\n case \"FA\":\n fa++;\n break;\n }\n }\n }\n }\n\n var crewData = {\n labels: [\"CP\", \"FO\", \"SA\", \"FA\"],\n datasets: [{\n label: \"Crew\",\n fillColor: \"rgba(33,150,243,0.5)\",\n strokeColor: \"rgba(33,150,243,0.8)\",\n highlightFill: \"rgba(33,150,243,0.75)\",\n highlightStroke: \"rgba(33,150,243,1)\",\n data: [cp, fo, sa, fa]\n }, {\n label: \"DHC\",\n fillColor: \"rgba(99,181,246,0.5)\",\n strokeColor: \"rgba(99,181,246,0.8)\",\n highlightFill: \"rgba(99,181,246,0.75)\",\n highlightStroke: \"rgba(99,181,246,1)\",\n data: [dhcCp, dhcFo, dhcSa, dhcFa]\n }]\n };\n var crewChart = {\n \"data\": crewData,\n \"options\": barOptions\n };\n return crewChart;\n };\n /**\r\n * Returns the meal Chart\r\n * @memberof FlightInfoCtrl\r\n * @param {object} paxInfo The passenger list\r\n * @return {object} mealChart\r\n */\n\n\n var generateMealChart = function generateMealChart(paxInfo) {\n var labels = [];\n var mealCdata = [];\n var mealYdata = [];\n\n for (var i = 0; i < paxInfo.PassengerSummaryC.SpecialMeals.length; i++) {\n labels.push(paxInfo.PassengerSummaryC.SpecialMeals[i].Name);\n mealCdata.push(paxInfo.PassengerSummaryC.SpecialMeals[i].Count);\n mealYdata.push(0);\n }\n\n for (var i = 0; i < paxInfo.PassengerSummaryY.SpecialMeals.length; i++) {\n var exists = false;\n\n for (var h = 0; h < labels.length; h++) {\n if (labels[h] == paxInfo.PassengerSummaryY.SpecialMeals[i].Name) {\n mealYdata[h] = paxInfo.PassengerSummaryY.SpecialMeals[i].Count;\n exists = true;\n break;\n }\n }\n\n if (!exists) {\n labels.push(paxInfo.PassengerSummaryY.SpecialMeals[i].Name);\n mealCdata.push(paxInfo.PassengerSummaryY.SpecialMeals[i].Count);\n mealYdata.push(0);\n }\n }\n\n var mealsData = {\n labels: labels,\n datasets: [{\n label: \"Business\",\n fillColor: \"rgba(139,195,74,0.5)\",\n strokeColor: \"rgba(139,195,74,0.8)\",\n highlightFill: \"rgba(139,195,74,0.75)\",\n highlightStroke: \"rgba(139,195,74,1)\",\n data: mealCdata\n }, {\n label: \"Economy\",\n fillColor: \"rgba(173,213,128,0.5)\",\n strokeColor: \"rgba(173,213,128,0.8)\",\n highlightFill: \"rgba(173,213,128,0.75)\",\n highlightStroke: \"rgba(173,213,128,1)\",\n data: mealYdata\n }]\n };\n var mealsChartData = {\n \"data\": mealsData,\n \"options\": barOptions\n };\n return mealsChartData;\n };\n /**\r\n * Returns the meal Chart\r\n * @memberof FlightInfoCtrl\r\n * @param {array} gates The total available gates\r\n * @param {array} FlightsFilters The flilters for the gates\r\n * @return {array} distinct_gates\r\n */\n\n\n var generateDistinctGates = function generateDistinctGates(gates, FlightsFilters) {\n var distinct_gates = [];\n\n for (var i = 0; i < gates.length; i++) {\n for (var j = 0; j < FlightsFilters.length; j++) {\n var row = gates[i].FlightNo + \",\" + gates[i].Codeshares.toString();\n\n if (row.indexOf(FlightsFilters[j].toString()) >= 0) {\n var distinct_gate = {\n FlightNo: gates[i].FlightNo,\n Gate: gates[i].DepGate,\n Arr: gates[i].Arrival,\n STD_lcl: gates[i].STD_lcl,\n STD: gates[i].STD,\n pax: null,\n Codeshares: gates[i].Codeshares\n };\n distinct_gates.push(distinct_gate);\n break;\n }\n }\n }\n\n return distinct_gates;\n };\n\n var applyPhoneNumber = function applyPhoneNumber() {\n flight.crew.forEach(function (user) {\n var phoneNumberInfo = crewPhoneNumbers.find(function (x) {\n return x.CrewId == user.id;\n });\n\n if (phoneNumberInfo) {\n user.PhoneNumber = phoneNumberInfo.PhoneNumber;\n } else {\n user.PhoneNumber = null;\n }\n });\n };\n\n var applyPreviousDuty = function applyPreviousDuty() {\n var dutyDate = moment(flight.ScheduledDeparture).startOf('day');\n flight.crew.forEach(function (user) {\n var previousDutyInfo = previousDuties.find(function (x) {\n return x.CrewId == user.id;\n });\n\n if (previousDutyInfo) {\n user.PreviousDuty = previousDutyInfo.PreviousDuty;\n } else {\n user.PreviousDuty = null;\n }\n\n if (user.PreviousDuty && user.PreviousDuty.isFlight) {\n var arrivalDate = user.PreviousDuty.ATA;\n if (!arrivalDate) arrivalDate = user.PreviousDuty.ETA;\n if (!arrivalDate) arrivalDate = user.PreviousDuty.STA;\n user.PreviousDuty.showArrivalDate = !moment(arrivalDate).startOf('day').isSame(dutyDate);\n var departureDate = user.PreviousDuty.ATA;\n if (!departureDate) departureDate = user.PreviousDuty.ETA;\n if (!departureDate) departureDate = user.PreviousDuty.STA;\n user.PreviousDuty.showDepartureDate = !moment(departureDate).startOf('day').isSame(dutyDate);\n }\n\n if (user.PreviousDuty && !user.PreviousDuty.isFlight) {\n user.PreviousDuty.showDate = !moment(user.PreviousDuty.GroundDutyDate).startOf('day').isSame(dutyDate);\n }\n });\n };\n\n var applyCrewCheckInStatus = function applyCrewCheckInStatus() {\n var crewCheckInStatuses = FlightCheckInsFactory.getFlightCrewCheckInFromStorage(flightId);\n flight.crew.forEach(function (user) {\n var statuses = crewCheckInStatuses.find(function (x) {\n return x.CrewId == user.id;\n });\n\n if (statuses) {\n user.CheckIn = statuses.CheckIn;\n user.WillBeThereAt = statuses.WillBeThereAt;\n } else {\n user.CheckIn = null;\n user.WillBeThereAt = null;\n }\n });\n };\n\n applyPhoneNumber();\n applyPreviousDuty();\n applyCrewCheckInStatus();\n PaxInfoFactory.setMaskPaxInfoInRoute(flight);\n $scope.flightCrewPreviousDuty = flight.crew.filter(function (x) {\n return x.PreviousDuty && x.PreviousDuty.isDifferent && (x.position == \"CP\" || x.position == \"FO\") && !x.isDHC;\n }).length;\n $scope.cabinCrewPreviousDuty = flight.crew.filter(function (x) {\n return x.PreviousDuty && x.PreviousDuty.isDifferent && (x.position == \"SA\" || x.position == \"FA\") && !x.isDHC;\n }).length;\n $scope.dhcCrewPreviousDuty = flight.crew.filter(function (x) {\n return x.PreviousDuty && x.PreviousDuty.isDifferent && x.isDHC;\n }).length;\n $scope.hasPreviousDuties = $scope.flightCrewPreviousDuty + $scope.cabinCrewPreviousDuty + $scope.dhcCrewPreviousDuty; //Update scopes for the CrewRoutePanel in Flight-page\n\n $scope.crewRouteInfoPanel = CrewRouteFactory.getCrewRouteInfoPanel(flight);\n $scope.saEligibility = flight.LineStatus != 'na'; // (flight.Position == \"SA\" || (flight.Position != \"SA\" && !flight.getSeniorAttendantsCount() && flight.Fleet.Id==2 ));\n //Manage Face Mask Panel visibility - Show only to SA or OA flights with no SA\n\n $scope.enableFaceMasks = enableFaceMasks && flight && $scope.saEligibility; //todo :: epap replace with flightId 1312896\n\n var aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId(flight.FlightId);\n $scope.state = 'flight';\n $scope.flight = flight;\n $scope.aircaftPositions = aircaftPositions;\n $scope.IsProvisional = true;\n $scope.flightZones = RenderFlightZones(flight.Zones);\n $scope.messages = MessageFactory.getMessagesFromIds(flight.messages);\n var messages = $scope.messages;\n $scope.openMessage = openMessage; //Initialize scope variables\n\n $scope.isEnabled = false;\n $scope.isPanelOpen = true;\n $scope.showConnFlights = true; //Charts\n\n $scope.crewChart = generateCrewChart(flight);\n $scope.generateMealChart = generateMealChart; //1226541\n\n PaxInfoFactory.getPaxInfoFromStorage(flight.FlightId, function (paxInfo) {\n $scope.paxInfo = paxInfo;\n\n if (paxInfo) {\n $scope.cStat = paxInfo.PaxTotalC / paxInfo.ConfigurationC * 100;\n $scope.yStat = paxInfo.PaxTotalY / paxInfo.ConfigurationY * 100;\n $scope.mealsChart = generateMealChart(paxInfo);\n var listSentTimestamp = new Date(paxInfo.LastRun).getTime();\n var DepartureTimestamp = new Date(flight.ScheduledDeparture).getTime(); //20 minutes before takeoff\n\n if (DepartureTimestamp - listSentTimestamp <= 1200000) {\n $scope.IsProvisional = false;\n }\n }\n });\n var flightArrivalTime = new Date(flight.ScheduledArrival).getTime();\n $scope.flightETA = flight.ETA ? new Date(flight.ETA).getTime() : flightArrivalTime; //Initialize scope functionality\n\n $scope.IsOld = _IsOld;\n $scope.isConnectedFlightClose = isConnectedFlightClose;\n $scope.TimeDifference = TimeDifference;\n $scope.openFlightConfig = openFlightConfig;\n $scope.openGates = openGates; //TODO : find a more angular way (EPAP)\n\n $scope.togglePanel = togglePanel; //TODO : find a more angular way (EPAP)\n\n $scope.toggleViewMode = toggleViewMode; //Initialize CSS classes\n\n $scope.getTextClass = getTextClass();\n $scope.getTopClass = getTopClass();\n $scope.getBottomClass = getBottomClass();\n $scope.hasIcon = hasIcon();\n $scope.getAssessmentTextClass = getAssessmentTextClass();\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('flightStatus', flightStatus);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name flightStatus\r\n * @restrict EA\r\n * @description\r\n * Implementation of flightStatus\r\n *\r\n * Initialize the flight Status panel needs to have flight in scope\r\n * @example\r\n * Usage:\r\n *
\r\n * @ngInject\r\n */\n\n function flightStatus(AircaftPositionsFactory) {\n function link($scope, element, attrs) {\n $scope.securitySearch = false;\n $scope.previousActualTAT = null;\n $scope.previousEstimatedTAT = null;\n $scope.previousScheduledTAT = null;\n $scope.previousDiffWithSceduled = null;\n $scope.nextActualTAT = null;\n $scope.nextEstimatedTAT = null;\n $scope.nextScheduledTAT = null;\n $scope.nextDiffWithSceduled = null;\n\n if ($scope.flight && $scope.flight.FlightId) {\n $scope.aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId($scope.flight.FlightId);\n }\n\n if ($scope.aircaftPositions != null) {//TurnAroundTime();\n }\n\n function TurnAroundTime() {\n var previousTemporaryActualValue;\n var nextTemporaryActualValue; //TurnAroundTime for previous flight\n\n if ($scope.aircaftPositions.PreviousATA && $scope.flight.ATD) {\n previousTemporaryActualValue = Date.DifferenceInMinutes($scope.aircaftPositions.PreviousATA, $scope.flight.ATD);\n $scope.previousActualTAT = normalizeMins(previousTemporaryActualValue);\n } else if ($scope.aircaftPositions.PreviousETA && $scope.flight.ETD) {\n previousTemporaryActualValue = Date.DifferenceInMinutes($scope.aircaftPositions.PreviousETA, $scope.flight.ETD);\n $scope.previousEstimatedTAT = normalizeMins(previousTemporaryActualValue);\n }\n\n if ($scope.aircaftPositions.PreviousSTA && $scope.flight.ScheduledDeparture) {\n var previousTemporaryScheduledValue = Date.DifferenceInMinutes($scope.aircaftPositions.PreviousSTA, $scope.flight.ScheduledDeparture);\n $scope.previousScheduledTAT = normalizeMins(previousTemporaryScheduledValue);\n var tempDiff = previousTemporaryActualValue - previousTemporaryScheduledValue; //difference (mins) between Actual and Scheduled\n\n if (tempDiff >= -70 && tempDiff <= 70) $scope.previousDiffWithSceduled = normalizeMins(tempDiff, true);\n } //TurnAroundTime for next flight\n\n\n if ($scope.flight.ATA && $scope.aircaftPositions.NextATD) {\n nextTemporaryActualValue = Date.DifferenceInMinutes($scope.aircaftPositions.flight.ATA, $scope.aircaftPositions.NextATD);\n $scope.nextActualTAT = normalizeMins(nextTemporaryActualValue);\n } else if ($scope.flight.ETA && $scope.aircaftPositions.NextETD) {\n nextTemporaryActualValue = Date.DifferenceInMinutes($scope.aircaftPositions.flight.ETA, $scope.aircaftPositions.NextETD);\n $scope.nextEstimatedTAT = normalizeMins(nextTemporaryActualValue);\n }\n\n if ($scope.flight.ScheduledArrival && $scope.aircaftPositions.NextSTD) {\n var nextTemporaryScheduledValue = Date.DifferenceInMinutes($scope.aircaftPositions.ScheduledArrival, $scope.aircaftPositions.NextSTD);\n $scope.nextScheduledTAT = normalizeMins(nextTemporaryScheduledValue);\n var tempDiff = nextTemporaryActualValue - nextTemporaryScheduledValue; //difference (mins) between Actual and Scheduled\n\n if (tempDiff >= -70 && tempDiff <= 70) $scope.nextDiffWithSceduled = normalizeMins(tempDiff, true);\n }\n }\n\n function normalizeMins(diffInMins, canBeNegativeNumber) {\n var returnString = \"\"; //negative value - return mins\n\n if (canBeNegativeNumber && diffInMins < 0) {\n returnString = diffInMins * -1 + \"mins less than scheduled\";\n } //positive value - return mins\n else if (canBeNegativeNumber) {\n returnString = diffInMins + \"mins more than scheduled\";\n } //positive value - return hours like \"2hrs 30mins\"\n else {\n returnString = Date.MinutesToString(diffInMins);\n }\n\n return returnString;\n }\n\n function needsSecuritySearch() {\n if ($scope.aircaftPositions.PreviousEU) {\n $scope.securitySearch = false;\n }\n\n if ($scope.aircaftPositions.PreviousCounty == \"SWITZERLAND\" || $scope.aircaftPositions.PreviousCounty == \"NORWAY\" || $scope.aircaftPositions.PreviousCounty == \"ICELAND\" || $scope.aircaftPositions.PreviousCounty == \"MONTENEGRO\") {\n $scope.securitySearch = false;\n }\n\n if ($scope.aircaftPositions.PreviousCounty == \"UNITED KINGDOM\" || $scope.aircaftPositions.PreviousCounty == \"FRANCE\") {\n $scope.securitySearch = true;\n }\n\n if ($scope.flight.ArrivalCountry == \"TURKEY\" || $scope.flight.ArrivalCountry == \"EGYPT\" || $scope.flight.ArrivalCountry == \"ISRAEL\" || $scope.flight.ArrivalCountry == \"JORDAN\" || $scope.flight.ArrivalCountry == \"SAUDI ARABIA\") {\n $scope.securitySearch = true;\n }\n }\n }\n\n return {\n restrict: 'EA',\n terminal: true,\n templateUrl: 'views/directives/flightStatus.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('GroundServicesFactory', GroundServicesFactory);\n /**\r\n * @memberOf CabinReports\r\n * @ngdoc factory\r\n * @name GroundServicesFactory\r\n * @description\r\n * Get Ground Services\r\n * @gnInject\r\n */\n\n function GroundServicesFactory(GenericService) {\n /**\r\n * Initialize the GroundServices\r\n * @memberof GroundServicesFactory\r\n */\n function GroundService() {\n this.Station = null;\n }\n\n var objType = 'groundServices';\n var objCallBack = GroundService;\n var service = {\n fromObjectList: fromObjectList,\n getGroundServicesFromStorage: getGroundServicesFromStorage,\n setGroundServicesToStorage: setGroundServicesToStorage,\n clearGroundServicesFromStorage: clearGroundServicesFromStorage,\n getGroundServicesByStation: getGroundServicesByStation,\n upsertGroundServices: upsertGroundServices\n };\n /**\r\n * Extend an array of Objects from the default GroundService Object\r\n * @memberof GroundServicesFactory\r\n * @param {Array} objList an Array Of ground Services\r\n * @returns {Array} groundServices\r\n */\n\n function fromObjectList(objList) {\n return GenericService.fromObjectList(objList, objCallBack);\n }\n /**\r\n * Get ground services from local storage\r\n * @memberof GroundServicesFactory\r\n * @returns {Array} groundServices \r\n */\n\n\n function getGroundServicesFromStorage() {\n return GenericService.list(objType, objCallBack);\n }\n /**\r\n * Save ground services to storage\r\n * @memberof GroundServicesFactory\r\n * @param {Array} List of ground services\r\n */\n\n\n function setGroundServicesToStorage(groundServices) {\n for (var i = 0; i < groundServices.length; i++) {\n for (var j = 0; j < groundServices[i].Services.length; j++) {\n // isDefault could be null\n if (groundServices[i].Services[j].IsDefault) groundServices[i].Services[j].Used = 1;else groundServices[i].Services[j].Used = 0;\n }\n }\n\n GenericService.saveAll(groundServices, objType, objCallBack);\n }\n /**\r\n * Remove the ground services from the local storage\r\n * @memberof GroundServicesFactory\r\n */\n\n\n function clearGroundServicesFromStorage() {\n GenericService.removeAll(objType, objCallBack);\n }\n /**\r\n * Get Ground Services of a current station from the local storage\r\n * @memberof GroundServicesFactory\r\n * @param {number} station \r\n * @return {object} GroundServices \r\n */\n\n\n function getGroundServicesByStation(station) {\n var objects = getGroundServicesFromStorage();\n if (objects == null) return [];\n var results = [];\n var arrayLength = objects.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (objects[i].Station == station) {\n results = objects[i].Services;\n }\n }\n\n return results;\n }\n /**\r\n * Upsert ground services\r\n * @memberof GroundServicesFactory\r\n */\n\n\n function upsertGroundServices(groundServices) {\n var newStations = groundServices.map(function (x) {\n return x.Station;\n });\n var servicesLS = this.getGroundServicesFromStorage();\n servicesLS = servicesLS.filter(function (x) {\n return !newStations.includes(x.Station);\n });\n var updatedServicesList = servicesLS.concat(groundServices);\n setGroundServicesToStorage(updatedServicesList);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('passengerEvents', passengerEvents);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name passengerEvents\r\n * @restrict E\r\n * @description\r\n * Implementation of passengerEvents\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function passengerEvents(ToolkitFactory, CustomerEventFactory) {\n function link(scope) {\n var Passengers = []; //Get all OneStopShop customer events of this flight\n\n var customerEvents = CustomerEventFactory.groupFlightCustomerEventsByPassenger(scope.flightId);\n ToolkitFactory.getToolkitItemsFromStorage(function (toolKitItems) {\n //Merge each event with its toolkit Item\n customerEvents.forEach(function (customerEvent) {\n customerEvent.OneStopShopEvents.forEach(function (event) {\n event.ToolkitItem = toolKitItems.find(function (x) {\n return x.Id == event.ToolkitItemId;\n });\n event.Treatment = toolKitItems.find(function (x) {\n return x.Id == event.ToolkitItemId;\n }).Treatments.find(function (t) {\n return t.Id == event.TreatmentId;\n });\n });\n }); // OneStopShopEvent Passengers\n\n customerEvents.forEach(function (customerEvent) {\n //Passenger already exists - Only add events\n if (Passengers.map(function (p) {\n return p.UCI;\n }).includes(customerEvent.UCI)) {\n Passengers.find(function (p) {\n return p.UCI == customerEvent.UCI;\n }).OneStopShopEvents = customerEvent.OneStopShopEvents;\n } //Add Passenger Info & Events\n else {\n var passenger = {\n UCI: customerEvent.UCI,\n GivenName: customerEvent.GivenName,\n Surname: customerEvent.Surname,\n SeatNo: customerEvent.SeatNo,\n OneStopShopEvents: customerEvent.OneStopShopEvents,\n numberOfEvents: customerEvent.OneStopShopEvents.length,\n isOpen: false\n };\n Passengers.push(passenger);\n }\n });\n scope.Passengers = Passengers;\n });\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/Flight/passengerEvents.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.filter('paxNames', paxNames);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc filter\r\n * @name paxNames\r\n * @description \r\n * List pax names in list and return $sce html \r\n * @ngInject\r\n */\n\n function paxNames($sce) {\n return function (input) {\n var html = '\"
C
Y
';\n html = html + \"
Passengers \";\n html = html + '
' + input.PassengerSummaryC.Passengers + \"
\";\n html = html + '
' + input.PassengerSummaryY.Passengers + '
';\n html = html + \"
PRM \";\n html = html + '
' + input.PassengerSummaryC.PRM + \"
\";\n html = html + '
' + input.PassengerSummaryY.PRM + '
';\n html = html + \"
UMNR \";\n html = html + '
' + input.PassengerSummaryC.UMNR + \"
\";\n html = html + '
' + input.PassengerSummaryY.UMNR + '
';\n html = html + \"
DEP \";\n html = html + '
' + input.PassengerSummaryC.DEP + \"
\";\n html = html + '
' + input.PassengerSummaryY.DEP + '
\\\"';\n return $sce.trustAsHtml(html);\n };\n }\n\n ;\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('SyncPaxCtrl', SyncPaxCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SyncPaxCtrl\r\n * @description \r\n * Get the latest PAX and gate Information\r\n * @ngInject\r\n */\n\n function SyncPaxCtrl($scope, InfoAPIService, $uibModalInstance, $route, flightId, LogService, FlightFactory, FlightSessionFactory, CourseFactory, CrewCallFactory, PreviousDutyFactory) {\n var flight = FlightFactory.getFlightFromTotalFlights(flightId);\n $scope.hideElements = true;\n $scope.showOnSuccess = false;\n $scope.showOnEmptyData = false;\n $scope.showOnSuccessNoFlightData = false;\n $scope.showOnOutOfDateRange = false;\n $scope.cancel = cancel;\n $scope.flightId = flightId;\n $scope.isFetchingFlightData = false;\n $scope.flightDataStatus = [{\n datatype: \"Flight Status\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Aircraft Movement\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Crew Info\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Crew Contacts\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, // {\n // \tdatatype: \"Aims Crew Memos\",\n // \tstatus: \"PENDING\",\n // \ttext: \"Pending...\"\n // },\n {\n datatype: \"Pax Info\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Meals\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Connections\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Campaigns\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Luggage Info\",\n status: \"PENDING\",\n text: \"Pending...\"\n }, {\n datatype: \"Training Info\",\n status: \"PENDING\",\n text: \"Pending...\"\n }];\n $uibModalInstance.closed.then(function () {\n $route.reload();\n });\n var isThisFlightSynced = false;\n /**\r\n * Close the modal\r\n * @memberof SyncPaxCtrl\r\n */\n\n function cancel() {\n $uibModalInstance.close('close');\n }\n\n ;\n var q = InfoAPIService.getPax(flightId);\n $scope.isFetchingFlightData = true;\n q.then(function (responseData) {\n updateStatusGenerator(responseData);\n $scope.isFetchingFlightData = !$scope.isFetchingFlightData;\n\n if (responseData == undefined || responseData.data == undefined || responseData.data.data == undefined) {\n var err = new Error();\n err.status = -1;\n var msg = \"ResponseData error in sync :\" + JSON.stringify(responseData);\n LogService.debug(msg, err);\n q.reject(err);\n } //Save training\n\n\n var trainingCourses = responseData.data.data.TrainingCourses;\n\n if (trainingCourses && trainingCourses.length) {\n trainingCourses.forEach(function (trainingCourse) {\n CourseFactory.upsertCourse(trainingCourse, function (course) {\n FlightSessionFactory.applyTraineeInfoToSession(course, course.Id, new moment(flight.DutyDate).format(\"YYYY-MM-DD\"), flight.DutyNo, flight.DutyDay, function (session) {});\n });\n });\n } //1. First remove all additional info (phone numbers & previous duties) for this flight\n\n\n CrewCallFactory.cleanFlightCrewNumbers(flightId);\n PreviousDutyFactory.cleanFlightPreviousDuties(flightId); //2. Then save any fetched info\n\n if (responseData.data.data.FlightInfo) {\n var crew = responseData.data.data.FlightInfo.crew;\n CrewCallFactory.saveFlightPhoneNumbers(flightId, crew, flight.ScheduledArrival, flight.ScheduledDeparture);\n PreviousDutyFactory.saveFlightPreviousDuties(flightId, crew);\n } //Save pax\n\n\n if (responseData.data.data.CabinServiceManagementLists) {\n for (var i = 0; i < responseData.data.data.CabinServiceManagementLists.length; i++) {\n if (responseData.data.data.CabinServiceManagementLists[i].FlightId == flightId) {\n //check for out of date range pax info\n var today = new Date().getTime();\n var paxDate = new Date(responseData.data.data.CabinServiceManagementLists[i].LastRun).getTime();\n\n if (paxDate <= today - 172800000) {\n $scope.showOnOutOfDateRange = true;\n break;\n }\n\n $scope.pax = responseData.data.data.CabinServiceManagementLists[i];\n $scope.showOnSuccess = true;\n isThisFlightSynced = true;\n break;\n }\n }\n\n if (!$scope.showOnSuccess) {\n $scope.showOnSuccessNoFlightData = true;\n } // $timeout(function () {\n // \t$uibModalInstance.close();\n // \t$route.reload();\n // }, 3000);\n\n } else {\n $scope.showOnEmptyData = true;\n }\n }, function (responseData) {\n updateStatusGenerator(responseData);\n $scope.isFetchingFlightData = !$scope.isFetchingFlightData;\n $scope.hideElements = false;\n });\n\n function updateStatusGenerator(data) {\n if (!data.data || !data.data.success) {\n for (var i = 0; i < $scope.flightDataStatus.length; i++) {\n $scope.flightDataStatus[i].status = \"FAIL\";\n $scope.flightDataStatus[i].text = \"Update failed\";\n }\n } else {\n if (!data.data.data.Campaigns.GetAssignmentsSuccess) {\n $scope.flightDataStatus[6].status = \"FAIL\";\n $scope.flightDataStatus[6].text = \"Update failed\";\n }\n\n var newDuty = data.data.data;\n InfoAPIService.updateFlightStatusSetter(newDuty, $scope.flightDataStatus);\n }\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('turnAroundTimes', turnAroundTimes);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name turnAroundTimes\r\n * @restrict EA\r\n * @description\r\n * Implementation of turnAroundTimes\r\n *\r\n * Initialize the turn Around Times panel needs to have flight in scope\r\n * @example\r\n * Usage:\r\n *
\r\n * @ngInject\r\n */\n\n function turnAroundTimes(AircaftPositionsFactory, turnArroundTimesAcTypes) {\n /**\r\n * Initialize turnAroundTimes\r\n * @memberof turnAroundTimes\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\n function link($scope, element, attrs) {\n $scope.showTaTpanel = false;\n var supportsTurnArroundTimes = $scope.flight && turnArroundTimesAcTypes.includes($scope.flight.AcType);\n\n if ($scope.flight && $scope.flight.FlightId && $scope.flight.ATD && supportsTurnArroundTimes) {\n var aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId($scope.flight.FlightId);\n\n if (aircaftPositions != null && aircaftPositions.PreviousATA) {\n /* var scheduledGroundTime = Date.DifferenceInMinutes(aircaftPositions.PreviousSTA, $scope.flight.ScheduledDeparture);\r\n var actualGroundTime = Date.DifferenceInMinutes(aircaftPositions.PreviousATA, $scope.flight.ScheduledDeparture);\r\n */\n var std = moment.utc($scope.flight.ScheduledDeparture);\n var atd = moment.utc($scope.flight.ATD);\n var startofTAT = moment.utc($scope.flight.ScheduledDeparture).add(-45, 'm');\n var prevATA = moment.utc(aircaftPositions.PreviousATA);\n var lateArrival = prevATA.diff(startofTAT, 'm');\n var scheduledTurnAroundTime = std.diff(startofTAT, 'm');\n var comparedValue = startofTAT;\n\n if (lateArrival > 0) {\n var comparedValue = prevATA;\n }\n\n var actualTurnAroundTime = atd.diff(comparedValue, 'm');\n $scope.scheduledTurnAroundTime = scheduledTurnAroundTime;\n $scope.actualTurnAroundTime = actualTurnAroundTime;\n $scope.lateArrival = lateArrival;\n $scope.showTaTpanel = true;\n }\n }\n }\n\n return {\n restrict: 'EA',\n terminal: true,\n templateUrl: 'views/directives/turnAroundTimes.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('AddFlightCtrl', AddFlightCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name AddFlightCtrl\r\n * @description \r\n * Add a new flight that is not in schedule\r\n * @ngInject\r\n */\n\n function AddFlightCtrl($scope, UserFactory, FlightFactory, AircraftTypeFactory, $uibModalInstance, $route) {\n $scope.isSecure = UserFactory.isSecure(); // cancel\n\n $scope.doCancel = doCancel; // add flight\n\n $scope.doAdd = doAdd; // setup datetime pickers\n\n var now = new Date();\n var minSelectableDate = new Date();\n var maxSelectableDate = new Date();\n minSelectableDate.setDate(now.getDate() - 15);\n maxSelectableDate.setDate(now.getDate() + 2);\n $scope.minSelectableDateStr = minSelectableDate.toString('dd-MM-yyyy');\n $scope.maxSelectableDateStr = maxSelectableDate.toString('dd-MM-yyyy');\n $scope.selectedDate = null;\n $scope.selectedTime = null;\n $scope.hstep = 1;\n $scope.mstep = 1;\n $scope.ismeridian = false;\n $scope.dateFormat = 'dd-MM-yyyy';\n $scope.hourFormat = \"HH:mm\";\n $scope.datepicker = {\n opened: false\n };\n $scope.openDatepicker = openDatepicker;\n $scope.createFlightFromUIValues = createFlightFromUIValues;\n $scope.processForm = processForm; // initialize form data\n\n $scope.formData = {}; // setup aircraft types\n\n var actypes = AircraftTypeFactory.getAircraftTypesFromStorage();\n if (!(actypes instanceof Array)) actypes = [];\n actypes.push({\n Code: 'other'\n });\n $scope.aircraftTypes = actypes;\n /**\r\n * Open Datepicker\r\n * @memberof AddFlightCtrl\r\n */\n\n function openDatepicker() {\n $scope.datepicker.opened = true;\n }\n /**\r\n * Close the modal\r\n * @memberof AddFlightCtrl\r\n */\n\n\n function doCancel() {\n $uibModalInstance.close('cancel');\n }\n /**\r\n * Add the flight to schedule\r\n * @memberof AddFlightCtrl\r\n */\n\n\n function doAdd() {\n $scope.processForm();\n }\n /**\r\n * Get the values from ui and create a flight \r\n * @memberof AddFlightCtrl\r\n */\n // \n\n\n function createFlightFromUIValues() {\n // get moment dt from controls\n var flightDate = $scope.formData.flightDateStr;\n var flightSTD = $scope.formData.flightTimeStr; // convert them to dates\n\n flightDate = new Date(flightDate);\n flightSTD = new Date(flightSTD); // combine date and time\n\n flightDate.setHours(flightSTD.getHours(), flightSTD.getMinutes(), 0, 0); // flightDate = flightDate.fromUTC();\n // get other flight details\n\n var flightNumber = $scope.formData.flightNumber;\n var flightDeparture = $scope.formData.flightDeparture;\n var flightDestination = $scope.formData.flightDestination;\n var flightRegNo = $scope.formData.flightRegNo;\n var flightAcType = null;\n if ($scope.formData.flightAcType != null) flightAcType = $scope.formData.flightAcType; // try to create a local flight\n\n var newFlight = FlightFactory.createLocalFlight(flightDate, flightNumber, flightDeparture, flightDestination, flightRegNo, flightAcType);\n return newFlight;\n }\n /**\r\n * Process and validate the form\r\n * @memberof AddFlightCtrl\r\n */\n\n\n function processForm() {\n // if all valid\n if ($scope.formFlight.$valid) {\n try {\n // try to create a local flight\n var newFlight = $scope.createFlightFromUIValues(); // save the local flight\n\n if (newFlight != null) {\n FlightFactory.saveLocalFlight(newFlight);\n }\n\n if (newFlight == null) {\n bootbox.alert(\"

Error

Unable to create a flight record.\");\n } else {\n (function () {\n $uibModalInstance.close();\n $route.reload();\n })();\n }\n } catch (e) {\n bootbox.alert(\"

Error

Unable to create a flight record due to unexpected error:\\n\" + e.message);\n }\n } else {\n bootbox.alert(\"Please fill in all the required fields.\");\n }\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('CalendarCtrl', CalendarCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CalendarCtrl\r\n * @description \r\n * View your schedule (flights and ground duties)\r\n * @ngInject\r\n */\n\n function CalendarCtrl($scope, defaultCalendarDate, LeaveRequestFactory, version, $location, FlightFactory, UserFactory, MemoFactory, MessageFactory, UpdateService, SyncLogFactory, $timeout, $uibModal, CrewRouteFactory, CrewHotelFactory, GroundDutyFactory, localStorageMD5Service, SettingsMain, TrainingSessionFactory, FlightSessionFactory, ScheduleAcknowledgeFactory, CheckInFactory, ExpiriesFactory, $route, TraineeCoursesDetailsFactory, RequestFactory) {\n var flights = FlightFactory.getFlightsFromStorage();\n var user = UserFactory.getUser();\n var isAssessmentEnabled = SettingsMain.getIsAssessmentEnabled();\n $scope.isSecure = UserFactory.isSecure();\n $scope.state = 'calendar';\n $scope.setupView = setupView;\n $scope.logged_user_info = user.aimsId + ' - ' + user.name;\n $scope.storageUsage = storageUsage();\n $scope.addFlight = addFlight;\n $scope.openSynch = openSynch;\n $scope.pendingOverdueReports = 0;\n $scope.draftReports = 0;\n $scope.completedReports = 0;\n $scope.isUserSA = user.position == 'SA' ? true : false;\n $scope.gotoUnreadMemos = gotoUnreadMemos;\n $scope.gotoMessages = gotoMessages;\n $scope.gotoLeaves = gotoLeaves;\n $scope.hasUnsetTraining = false;\n $scope.hasScheduleChanged = false;\n $scope.acknowledge = acknowledge;\n $scope.showPasswordExpiryAlert = false;\n $scope.showExpiriesAlertCalendar = false;\n $scope.showSubmissionDeadlineAlertCalendar = false;\n $scope.expiryList = [];\n $scope.submissionDeadline = null;\n $scope.showCheckInAction = false;\n $scope.openCheckIn = openCheckInModal;\n $scope.searchPastGroundDuties = searchPastGroundDuties;\n $scope.hasManualEntry = false;\n $scope.gotoGroundDutyInfo = gotoGroundDutyInfo;\n $scope.removeManualEntry = removeManualEntry;\n $scope.daysDiff = daysDiff;\n $scope.hasTraineeCourse = false;\n $scope.gotoFlightInfo = gotoFlightInfo;\n $scope.removeFlightTrainingManualEntry = removeFlightTrainingManualEntry;\n $scope.gotoCrewRouteInfo = gotoCrewRouteInfo;\n $scope.pastTrainingsViewSummary = pastTrainingsViewSummary;\n $scope.viewPastTrainings = false;\n $scope.removePendingGDEntry = removePendingGDEntry;\n $scope.removePendingFlightEntry = removePendingFlightEntry;\n $scope.passwordExpiry = {\n showAlert: false,\n lastChange: null,\n daysLeft: null\n };\n\n function pastTrainingsViewSummary() {\n $scope.viewPastTrainings = !$scope.viewPastTrainings;\n }\n\n var groundSessions = [];\n var flightSessions = [];\n TrainingSessionFactory.getAll(function (savedGroundSessions) {\n FlightSessionFactory.getAll(function (savedFlightSessions) {\n groundSessions = savedGroundSessions;\n flightSessions = savedFlightSessions;\n $scope.setupView(false);\n });\n });\n\n if (version) {\n $scope.version = version.replace('appVersion_', '');\n } else {\n $scope.version = '';\n }\n /**\r\n * Calculates the local storage Usage\r\n * @memberof CalendarCtrl\r\n * @return {string} usage\r\n */\n\n\n function storageUsage() {\n var usage = localStorageMD5Service.usedSize();\n return usage;\n }\n /**\r\n * Calculates days left\r\n * @memberof CalendarCtrl\r\n * @return {string} usage\r\n */\n\n\n function daysDiff(date) {\n var today = moment().startOf('day');\n var expiryDate = moment(date);\n return expiryDate.diff(today, 'days');\n }\n /**\r\n * Setups Calendar View\r\n * @memberof CalendarCtrl\r\n * @param {boolean} isReload\r\n */\n\n\n function setupView(isReload) {\n if (!UserFactory.isLoggedIn()) {\n $location.path(\"/login\");\n }\n\n $scope.NeedsToSync = UpdateService.updater();\n $scope.number_of_messages = MessageFactory.getMessagesFromStorage().length;\n $scope.number_of_messages_not_readen = MessageFactory.getCountOfUnreadMessages();\n $scope.leaveRequest = LeaveRequestFactory.getLeaveRequestInformation();\n $scope.leaveRequestCloseDate = $scope.leaveRequest ? moment($scope.leaveRequest.CloseDate).format('Do of MMMM') : null;\n $scope.expiryList = ExpiriesFactory.getCrewExpiriesFromStorage();\n $scope.submissionDeadline = RequestFactory.getSubmissionDeadlineDateFromStorage(); //Get count of unread memos but remove the ones that belong in 'Training Surveys' Category\n\n MemoFactory.getUnreadMemos(function (memos) {\n $scope.unreadMemosCount = memos && memos.length || 0;\n }); // read the flights from the local storage and display them\n\n var flights = FlightFactory.getFlightsFromStorageAndCheckIfTooOld(); // also load the flights created by the user\n\n flights = FlightFactory.getLocalFlightsAndMergeWithServerFlights(flights); // if no local flights are found then force sync\n\n if (!isReload) {\n needsToSync = true;\n }\n\n var crewRoutes = CrewRouteFactory.getCrewRoutesFromStorage();\n var groundDuties = GroundDutyFactory.getGroundDutiesFromStorage();\n var crewHotels = CrewHotelFactory.getCrewHotelsFromStorage();\n var crewRoutesEvents = formatCrewRoutes(crewRoutes);\n var traineeGroundCourses = TraineeCoursesDetailsFactory.getTraineeCourses();\n var groundDutiesEvents = formatGroundDuties(groundDuties, traineeGroundCourses); // Get incomplete past duties\n\n $scope.totalIncompleteGD = [];\n $scope.totalIncompleteGD = groundDuties.filter(function (x) {\n return x.isManualEntry == true && !x.hasPendingCourse;\n }); // Flight duties\n\n $scope.totalIncompleteFlightDuties = [];\n $scope.totalIncompleteFlightDuties = crewRoutes.filter(function (x) {\n return x.isManualEntry && !x.hasPendingCourse;\n }); //\n\n if ($scope.totalIncompleteGD.length > 0 || $scope.totalIncompleteFlightDuties.length > 0) {\n $scope.showPastTrainingsSummary = true;\n } // Used for pending trainings notification \n\n\n $scope.manualGroundDuties = GroundDutyFactory.getManualGroundDutiesFromStorage();\n findManualEntries($scope.manualGroundDuties);\n $scope.manualFlightTrainings = CrewRouteFactory.getManualFlightTrainingsFromStorage();\n findManualFlightTrainingEntries($scope.manualFlightTrainings);\n var traineeFlightCourses = TraineeCoursesDetailsFactory.getFlightCourses();\n var flightEvents = formatFlights(flights, traineeFlightCourses);\n var crewHotelsEvents = formatHotels(crewHotels);\n var events = flightEvents.concat(groundDutiesEvents).concat(crewRoutesEvents).concat(crewHotelsEvents);\n var specialDates = findScheduleChangedDates();\n $scope.events = events;\n calendar(events, specialDates);\n var needsToSync = false; // check the last sync date\n\n var lastLog = SyncLogFactory.getSyncLog();\n var canShowSync = true;\n\n if (lastLog == null) {\n needsToSync = true;\n } else {\n canShowSync = lastLog.canShowSync(); //used to avoid showing again and again the dialog :: delay X minutes before showing again\n\n if (lastLog.date == null) needsToSync = true;else if (lastLog.date != null) {\n if (Date.today().add(-1).days().toUTC().isAfter(new Date(lastLog.date).toUTC()) || lastLog.forceSync) {\n if (!isReload) needsToSync = true;\n }\n }\n }\n\n var isOpenUpdateModal = ($(\".modal-updating\").data('bs.modal') || {\n isShown: false\n }).isShown;\n\n if (needsToSync && canShowSync && !isOpenUpdateModal) {\n $scope.openSynch();\n } else {\n MemoFactory.getMandatoryUnreadMemos(function (memos) {\n $scope.mandatoryUnread = memos.length;\n\n if ($scope.mandatoryUnread > 0) {\n openMandatoryModal();\n }\n });\n }\n\n $scope.showExpiriesAlertCalendar = showExpiriesAlertCalendar();\n $scope.showSubmissionDeadlineAlertCalendar = showSubmissionDeadlineAlertCalendar();\n $scope.showCheckInAction = showCheckInAction();\n preparePasswordExpiryData();\n showReminderModal();\n }\n /**\r\n * Finds the dates with a change on their schedule\r\n * @memberof CalendarCtrl\r\n * @returm {array} scheduleChangedDates\r\n */\n\n\n function findScheduleChangedDates() {\n var scheduleChangedDates = ScheduleAcknowledgeFactory.getScheduleChangesFromStorage();\n $scope.hasScheduleChanged = scheduleChangedDates.some(function (s) {\n return s;\n });\n return scheduleChangedDates;\n }\n /**\r\n * Finds the dates with manual pending training entries on their schedule\r\n * @memberof CalendarCtrl \r\n */\n\n\n function findManualEntries(manualDuties) {\n for (var i = 0; i < manualDuties.length; i++) {\n if (manualDuties[i].hasPendingCourse) {\n $scope.hasManualEntry = true;\n break;\n }\n }\n }\n\n function findManualFlightTrainingEntries(manualFlightTrainings) {\n for (var i = 0; i < manualFlightTrainings.length; i++) {\n if (manualFlightTrainings[i].hasPendingCourse) {\n $scope.hasManualEntry = true;\n break;\n }\n }\n }\n /**\r\n * Initialize Calendar\r\n * @memberof CalendarCtrl\r\n * @param {array} events Flights and Ground duties \r\n * @param {array} specialDates The Schedule Changed Dates\r\n */\n\n\n function calendar(events, specialDates) {\n $(\"#calendar\").fullCalendar({\n defaultView: getDefaultView(),\n defaultDate: defaultCalendarDate,\n firstDay: 1,\n lang: 'en',\n editable: false,\n draggable: false,\n selectable: false,\n selectHelper: false,\n unselectAuto: false,\n disableResizing: false,\n droppable: false,\n fixedWeekCount: false,\n nextDayThreshold: \"00:00:00\",\n header: {\n left: 'title',\n center: '',\n right: 'month,listMonth today prev,next'\n },\n timeFormat: 'HH:mm',\n displayEventEnd: true,\n events: events,\n eventRender: function eventRender(event, element, icon) {\n if ($('#calendar').fullCalendar('getView').type === 'listMonth') {\n element.find('.fc-list-item-title').addClass('listview-icon');\n $.each(event.className, function (index, icon) {\n element.addClass(event.listViewColor);\n }); // $.each(event.icons, function (index, icon) {\n // element.find('.listview-icon').prepend(\" \");\n // });\n\n if (!event.description == \"\") {\n element.find('.fc-list-item-title').append(\"\" + \" \" + event.description + \"\");\n }\n\n if (!event.icon == \"\") {\n element.find('.fc-list-item-title').append(\"\");\n }\n\n if (!event.second_icon == \"\") {\n element.find('.fc-list-item-title').append(\"\");\n }\n\n if (!event.third_icon == \"\") {\n element.find('.fc-list-item-title').append(\"\");\n }\n } else {\n if (event.type == \"crewRoute\" || event.type == \"hotel\") {\n element.find('.fc-time').remove();\n }\n\n element.find('.fc-title').prepend(\"
\");\n\n if (!event.description == \"\") {\n if (event.routeIndicators && event.routeIndicators.length > 0) {\n var routeIndicatorLetters = \"\";\n\n for (var j = 0; j < event.routeIndicators.length; j++) {\n var letter = \"\" + event.routeIndicators[j].routeIndicatorCode + \"\";\n routeIndicatorLetters = routeIndicatorLetters + letter;\n }\n\n element.find('.fc-title').append(\"
\" + event.description + \"\" + routeIndicatorLetters + \"
\");\n } else {\n element.find('.fc-title').append(\"
\" + event.description + \"
\");\n }\n }\n\n if (!event.icon == \"\") {\n element.find('.fc-title').append(\"\");\n }\n\n if (!event.second_icon == \"\") {\n element.find('.fc-title').append(\"\");\n }\n\n if (!event.third_icon == \"\") {\n element.find('.fc-title').append(\"\");\n }\n }\n },\n dayRender: function dayRender(date, cell) {\n for (var i = 0; i < specialDates.length; i++) {\n var objdate = new Date(specialDates[i]);\n if (date._d.getFullYear() == objdate.getFullYear() && date._d.getDate() == objdate.getDate() && date._d.getMonth() == objdate.getMonth()) cell.addClass('bg-yellow');\n }\n },\n dayClick: function dayClick(date, jsEvent, view) {},\n eventClick: function eventClick(calEvent, jsEvent, view) {\n if (calEvent.type == \"flight\") {\n $timeout(function () {\n gotoFlightInfo(calEvent._id);\n });\n } else if (calEvent.type == \"groundDuty\") {\n $timeout(function () {\n gotoGroundDutyInfo(calEvent._id);\n });\n } else if (calEvent.type == \"crewRoute\") {\n $timeout(function () {\n gotoCrewRouteInfo(calEvent.dutyNo, calEvent.dutyDay);\n });\n }\n },\n height: 'auto'\n });\n\n function getDefaultView() {\n var calendarStyle = SettingsMain.getCalendarViewStyle();\n\n if (calendarStyle == null) {\n calendarStyle = detectMobile() ? \"listMonth\" : \"month\";\n }\n\n return calendarStyle;\n }\n\n function detectMobile() {\n var isMobile = window.innerWidth <= 800 && window.innerHeight <= 735;\n return isMobile;\n }\n\n $('.fc-listMonth-button').click(function () {\n SettingsMain.setCalendarViewStyle('listMonth');\n });\n $('.fc-month-button').click(function () {\n SettingsMain.setCalendarViewStyle('month');\n });\n }\n /**\r\n * Transform flights in calendar events\r\n * @memberof CalendarCtrl\r\n * @param {array} flights The Scheduled Flights \r\n * @return {array} events \r\n */\n\n\n function formatFlights(flights, traineeFlightCourses) {\n var flightEvents = [];\n\n for (var i = 0; i < flights.length; i++) {\n var description = flights[i].getRoute();\n var title = flights[i].FlightNo;\n var third_icon = \"\";\n var flightCourseStatuses = [];\n var flightCoursesFlat = [];\n\n if (flights[i].TrainingIndicatorCode) {\n title = title + \" \" + flights[i].TrainingIndicatorCode;\n }\n /* Trainee flight courses */\n\n\n var relatedFlightTraineeCourses = [];\n\n for (var j = 0; j < traineeFlightCourses.length; j++) {\n if (flights[i].IsTrainee == true && flights[i].FlightId == traineeFlightCourses[j].FlightId) {\n relatedFlightTraineeCourses = traineeFlightCourses.find(function (x) {\n return x.FlightId == flights[i].FlightId;\n });\n flightCoursesFlat = flightCoursesFlat.concat(relatedFlightTraineeCourses);\n /* NotSet = 0,\r\n InProgress = 1,\r\n Completed = 2,\r\n Pending = 3,\r\n NeedsApproval = 4,\r\n NotCompleted = 5 \r\n */\n }\n\n if (flightCoursesFlat.length > 0) {\n console.log(relatedFlightTraineeCourses);\n console.log(flightCourseStatuses);\n }\n }\n\n if (flightCoursesFlat.length > 0) {\n flightCoursesFlat.forEach(function (x) {\n flightCourseStatuses.push(x.Status);\n });\n }\n\n if (flightCourseStatuses.includes(1)) {\n //Pending\n third_icon = \"fa-graduation-cap text-blue\";\n } else if (flightCourseStatuses.includes(2)) {\n //Completed\n third_icon = \"fa-graduation-cap text-green\";\n } else if (flightCourseStatuses.includes(4) || flightCourseStatuses.includes(5)) {\n //Needs approval or stopped\n third_icon = \"fa-graduation-cap text-orange\";\n }\n\n var classname = \"\";\n var icon = \"fa-plane\";\n var second_icon = \"\";\n var id = flights[i].FlightId;\n var type = \"flight\";\n var listViewColor = \"\";\n /* Weights for status of reports\r\n 6 --> na\r\n 5 --> draft\r\n 4 --> pendingoverdue\r\n 3 --> pending\r\n 2 --> completed\r\n 1 --> synched */\n\n var CabinReportStatusWeight = 0;\n if (flights[i].LineStatus === 'na') CabinReportStatusWeight = 6;else if (flights[i].LineStatus === 'pending') CabinReportStatusWeight = 3;else if (flights[i].LineStatus === 'pendingoverdue') {\n CabinReportStatusWeight = 4;\n $scope.pendingOverdueReports++;\n } else if (flights[i].LineStatus === 'draft' || flights[i].LineStatus === 'draftotheruser') {\n $scope.draftReports++;\n CabinReportStatusWeight = 5;\n } else if (flights[i].LineStatus === 'completed' || flights[i].LineStatus === 'completedotheruser') {\n $scope.completedReports++;\n CabinReportStatusWeight = 2;\n } else if (flights[i].LineStatus === 'stored' || flights[i].LineStatus === 'storedotheruser' || flights[i].LineStatus === 'stored+otheruser' || flights[i].LineStatus === 'synched' || flights[i].LineStatus === 'synchedotheruser') {\n CabinReportStatusWeight = 1;\n } //Remove Assessment Weight For Coloring\n\n /* var AssessmentStatusWeight = 0;\r\n if (isAssessmentEnabled && flights[i].assessment){\r\n if(flights[i].assessment.IsExist || flights[i].assessment.Status == 'Stored'){\r\n AssessmentStatusWeight = 1\r\n }else if(flights[i].assessment.Status == 'Completed'){\r\n AssessmentStatusWeight = 2;\r\n }else if(flights[i].assessment.Status == 'Pending'){\r\n AssessmentStatusWeight = 3;\r\n }else if(flights[i].assessment.Status == 'Draft'){\r\n AssessmentStatusWeight = 5;\r\n }\r\n }*/\n\n var statusWeight = CabinReportStatusWeight; // var statusWeight = CabinReportStatusWeight > AssessmentStatusWeight ? CabinReportStatusWeight : AssessmentStatusWeight;\n\n if (statusWeight == 6) {\n if (flights[i].IsDHC) {\n classname = \"fc-aluminum\";\n icon = \"\";\n listViewColor = \"lv-aluminium\";\n } else {\n classname = \"fc-white\";\n icon = \"\";\n listViewColor = \"lv-white\";\n }\n } else if (statusWeight == 5) {\n classname = \"fc-orange\";\n icon = \"fa-pencil\";\n listViewColor = \"lv-orange\";\n } else if (statusWeight == 4) {\n classname = \"fc-seablue\";\n icon = \"fa-exclamation-triangle text-lemon\";\n listViewColor = \"lv-seablue\";\n } else if (statusWeight == 3) {\n classname = \"fc-blue\";\n icon = \"fa-plus\";\n listViewColor = \"lv-blue\";\n } else if (statusWeight == 2) {\n classname = \"fc-purple\";\n icon = \"fa-check-circle\";\n listViewColor = \"lv-purple\";\n } else if (statusWeight == 1) {\n classname = \"fc-green\";\n icon = \"fa-cloud-download\";\n listViewColor = \"lv-green\";\n }\n\n if (flights[i].IsScheduleChanged && flights[i].LineStatus != 'na') {\n classname = classname + \" text-yellow-important\";\n }\n\n if (flights[i].LineStatus === 'draftotheruser' || flights[i].LineStatus === 'completedotheruser' || flights[i].LineStatus === 'synchedotheruser' || flights[i].LineStatus === 'storedotheruser' || flights[i].LineStatus === 'stored+otheruser') second_icon = \"fa-user\";\n var IsScheduleChanged = flights[i].IsScheduleChanged;\n var ScheduledDeparture = flights[i].ScheduledDeparture;\n\n if (flights[i].ScheduledArrival == null) {\n var ScheduledArrival = ScheduledDeparture;\n } else {\n var ScheduledArrival = flights[i].ScheduledArrival;\n }\n\n var event = {\n _id: id,\n title: title,\n start: ScheduledDeparture,\n end: ScheduledArrival,\n description: description,\n icon: icon,\n second_icon: second_icon,\n className: classname,\n type: type,\n isScheduleChanged: IsScheduleChanged,\n listViewColor: listViewColor,\n third_icon: third_icon\n };\n flightEvents.push(event);\n }\n\n return flightEvents;\n }\n /**\r\n * Transform Ground Duties in calendar events\r\n * @memberof CalendarCtrl\r\n * @param {array} duties The Scheduled Ground Duties \r\n * @return {array} events \r\n */\n\n\n function formatGroundDuties(duties, traineeGroundCourses) {\n var groundEvents = [];\n var now = moment.utc();\n\n for (var i = 0; i < duties.length; i++) {\n var description = duties[i].Code;\n var title = duties[i].Title ? duties[i].Title : duties[i].Duty;\n var classname = \"fc-white\";\n var icon = \"\";\n var second_icon = \"\";\n\n if (duties[i].RelatedGroundDuties && duties[i].RelatedGroundDuties.length > 1) {\n icon = \"fa-graduation-cap\"; // icon only if training\n //Get ground courses\n\n var courseStatuses = [];\n var coursesFlat = [];\n\n for (var j = 0; j < duties[i].RelatedGroundDuties.length; j++) {\n /* Trainee ground courses */\n if (traineeGroundCourses.length > 0) {\n var relatedTraineeCourse = traineeGroundCourses.find(function (x) {\n return x.GroundDutyId == duties[i].Id;\n });\n }\n\n var relatedDutyCourse = duties[i].RelatedGroundDuties[j].Courses;\n\n if (relatedDutyCourse) {\n coursesFlat = coursesFlat.concat(relatedDutyCourse);\n }\n\n if (relatedTraineeCourse) {\n coursesFlat = coursesFlat.concat(relatedTraineeCourse);\n }\n\n coursesFlat.forEach(function (x) {\n courseStatuses.push(x.Status);\n });\n }\n /*Statuses\r\n Completed : session has been sent\r\n Outdated :\tsession submission is overdue\r\n Draft\t : session completion has started but not submitted\r\n Pending : session submission not yet due\r\n */\n\n /* NotSet = 0,\r\n InProgress = 1,\r\n Completed = 2,\r\n Pending = 3,\r\n NeedsApproval = 4,\r\n NotCompleted = 5 \r\n */\n\n\n if (courseStatuses.includes(\"Pending\") || courseStatuses.includes(1)) {\n //Pending\n classname = \"fc-blue-inverted\"; //Outdated\n\n var dutyEnd = moment.utc(duties[i].DutyEnd);\n var duration = moment.duration(now.diff(dutyEnd)).asHours();\n\n if (duration > 1) {\n if (courseStatuses.includes(\"Pending\") || courseStatuses.includes('1')) $scope.hasUnsetTraining = true;\n classname = \"fc-seablue-inverted\";\n second_icon = \"fa-exclamation-triangle text-yellow second-icon-training\"; // isManualEntry = true;\n } //Draft\n\n\n var courseId = coursesFlat[0].CourseId; // Fix msis // each duty should contain ONLY ONE COURSE\n\n var duty = duties[i];\n\n if (groundSessions && groundSessions.length) {\n var existingSession = groundSessions.find(function (s) {\n return s.courseId == courseId && s.day == duty.DutyDateS && s.dutyId == duty.Id;\n });\n\n if (existingSession && !existingSession.HasLimitedInfo && existingSession.trainees && existingSession.trainees.length) {\n //a training session with trainees exists\n classname = \"fc-orange-inverted\";\n icon = \"fa-graduation-cap\";\n second_icon = \"\"; // isManualEntry = true;\n }\n }\n } else if (courseStatuses.includes(\"Completed\") || courseStatuses.includes(2)) {\n //Completed\n classname = \"fc-green-inverted \";\n } else if (courseStatuses.includes(4) || courseStatuses.includes(5)) {\n //Needs approval or stopped\n classname = \"fc-orange-inverted\";\n }\n }\n\n if (duties[i].Unread) {\n second_icon = \"fa-envelope text-orange\";\n }\n\n var id = duties[i].Id;\n var type = \"groundDuty\";\n var start = duties[i].DutyBegin ? duties[i].DutyBegin : duties[i].DutyDateS ? duties[i].DutyDateS : duties[i].DutyDate;\n var end = duties[i].DutyEnd;\n var listViewColor = \"lv-white\";\n var event = {\n _id: id,\n title: title,\n start: start,\n end: end,\n description: description,\n icon: icon,\n second_icon: second_icon,\n className: classname,\n type: type,\n listViewColor: listViewColor\n };\n groundEvents.push(event);\n }\n\n return groundEvents;\n }\n /**\r\n * Transform Crew Routes in calendar events\r\n * @memberof CalendarCtrl\r\n * @param {array} routes The Scheduled Crew Routes \r\n * @return {array} events \r\n */\n\n\n function formatCrewRoutes(routes) {\n var crewRouteEvents = [];\n var now = moment.utc();\n\n for (var i = 0; i < routes.length; i++) {\n var description = routes[i].Route; // var title = (duties[i].Title)? duties[i].Title : duties[i].Duty;\n\n var classname = \"fc-white\";\n var icon = \"\";\n var second_icon = \"\";\n var assessmentStatus = \"\";\n\n if (isAssessmentEnabled && routes[i].AssessmentInfo) {\n if (routes[i].AssessmentInfo.IsExist || routes[i].AssessmentInfo.Status == \"Stored\") {\n assessmentStatus = \"Synced\"; //classname = \"fc-green-inverted \";\n } else if (routes[i].AssessmentInfo.Status == \"Pending\") {\n assessmentStatus = \"Pending\"; //classname = \"fc-blue-inverted\";\n } else if (routes[i].AssessmentInfo.Status == \"Draft\") {\n assessmentStatus = \"Draft\"; //classname = \"fc-orange-inverted\";\n } else if (routes[i].AssessmentInfo.Status == \"Completed\") {\n assessmentStatus = \"Completed\"; //classname = \"fc-purple-inverted\";\n }\n } //Get ground courses\n\n\n var courseStatuses = [];\n var courses = routes[i].Courses;\n courses.forEach(function (x) {\n courseStatuses.push(x.Status);\n });\n /*Statuses\r\n Completed : session has been sent\r\n Outdated :\tsession submission is overdue\r\n Draft\t : session completion has started but not submitted\r\n Pending : session submission not yet due\r\n */\n\n var trainingStatus = \"\";\n\n if (courseStatuses.includes(\"Pending\")) {\n //Pending\n trainingStatus = \"Pending\"; //Outdated\n\n var dutyEnd = moment.utc(routes[i].DutyEnd);\n var duration = moment.duration(now.diff(dutyEnd)).asHours();\n\n if (duration > 1) {\n if (courseStatuses.includes(\"Pending\")) $scope.hasUnsetTraining = true;\n trainingStatus = \"Outdated\";\n } //Draft\n\n\n var courseIds = courses.map(function (x) {\n return x.CourseId;\n });\n var route = routes[i];\n\n if (flightSessions && flightSessions.length) {\n //TODO msis fix\n var dutyBegin = new moment(route.DutyBegin).format(\"YYYY-MM-DD\");\n var dutyEnd = new moment(route.DutyEnd).format(\"YYYY-MM-DD\");\n var existingSessions = flightSessions.filter(function (s) {\n return courseIds.includes(s.courseId) && (new moment(s.day).isSame(dutyBegin) || new moment(s.day).isSame(dutyEnd) || new moment(s.day).isBetween(dutyBegin, dutyEnd)) && s.dutyDay == route.DutyDay && s.dutyNo == route.DutyNo;\n });\n\n if (existingSessions && existingSessions.some(function (x) {\n return !x.HasLimitedInfo && x.trainees && x.trainees.length;\n })) {\n //a training session with trainees exists\n trainingStatus = \"Draft\";\n }\n }\n } else if (courseStatuses.includes(\"Completed\")) {\n //Completed\n trainingStatus = \"Completed\";\n classname = \"fc-green-inverted \";\n } // Status outcome form bot assessment and training\n\n\n if (trainingStatus == \"Outdated\") {\n second_icon = \"fa-exclamation-triangle text-yellow second-icon-training\";\n classname = \"fc-seablue-inverted\";\n } else if (trainingStatus == \"Draft\" || assessmentStatus == \"Draft\") {\n classname = \"fc-orange-inverted\";\n } else if (trainingStatus == \"Pending\" || assessmentStatus == \"Pending\") {\n classname = \"fc-blue-inverted\";\n } else if (assessmentStatus == \"Completed\") {\n classname = \"fc-purple-inverted\";\n } else if (trainingStatus == \"Completed\" || assessmentStatus == \"Synced\") {\n classname = \"fc-green-inverted\";\n }\n\n if (courses && courses.length) {\n icon = \"fa-graduation-cap\";\n }\n\n var routeIndicators = [];\n\n if (routes[i].RouteIndicators) {\n // Swap : [RECTYPE] = 106\n // Pre-Assigned : [RECTYPE] = 1\n // Requested : [RECTYPE] = 100\n var routeIndicatorCodes = routes[i].RouteIndicators.split(',').map(Number);\n\n for (var j = 0; j < routeIndicatorCodes.length; j++) {\n var routeIndicatorCode = \"\";\n var routeIndicatorColor = \"\";\n\n if (routeIndicatorCodes[j]) {\n if (routeIndicatorCodes[j] == 106) {\n routeIndicatorCode = \"S\";\n routeIndicatorColor = \"text-purple\";\n } else if (routeIndicatorCodes[j] == 1) {\n routeIndicatorCode = \"P\";\n routeIndicatorColor = \"text-teal\";\n } else if (routeIndicatorCodes[j] == 100) {\n routeIndicatorCode = \"R\";\n }\n\n if (routeIndicatorCode.length > 0) {\n routeIndicators.push({\n routeIndicatorCode: routeIndicatorCode,\n routeIndicatorColor: routeIndicatorColor\n });\n }\n }\n }\n } // var id = routes[i].Id;\n\n\n var type = \"crewRoute\";\n var dutyNo = routes[i].DutyNo;\n var dutyDay = routes[i].DutyDay;\n var start = routes[i].DutyBegin ? routes[i].DutyBegin : routes[i].DutyDateS ? routes[i].DutyDateS : routes[i].DutyDate;\n var end = routes[i].DutyEnd;\n var listViewColor = \"lv-white\";\n var event = {\n // _id:id,\n // title: title,\n dutyNo: dutyNo,\n dutyDay: dutyDay,\n start: start,\n end: end,\n description: description,\n icon: icon,\n second_icon: second_icon,\n className: classname,\n type: type,\n listViewColor: listViewColor,\n routeIndicators: routeIndicators\n };\n crewRouteEvents.push(event);\n }\n\n return crewRouteEvents;\n }\n /**\r\n * Transform Crew Hotels in calendar events\r\n * @memberof CalendarCtrl\r\n * @param {array} crew hotels \r\n * @return {array} events \r\n */\n\n\n function formatHotels(hotels) {\n var crewRouteEvents = [];\n\n for (var i = 0; i < hotels.length; i++) {\n //var description = hotels[i].HotelName;\n var title = hotels[i].HotelName;\n var classname = \"fc-gray-inverted\";\n var icon = \"fa-bed\";\n var second_icon = \"\"; // var id = routes[i].Id;\n\n var type = \"hotel\";\n var start = moment(hotels[i].DutyDate).endOf('day').toJSON(); // var end = hotels[i].DutyDate;\n\n var listViewColor = \"lv-white\";\n var event = {\n // _id:id,\n title: title,\n start: start,\n end: start,\n //description:description,\n icon: icon,\n second_icon: second_icon,\n className: classname,\n type: type,\n listViewColor: listViewColor\n };\n crewRouteEvents.push(event);\n }\n\n return crewRouteEvents;\n }\n /** Removes manual training entry */\n\n\n function removeManualEntry(groundDuty) {\n GroundDutyFactory.removeGroundDuty(groundDuty);\n $route.reload();\n }\n /**\r\n * Removes manual flight training entry \r\n * @param {*} dutyNo \r\n * @param {*} dutyDay \r\n */\n\n\n function removeFlightTrainingManualEntry(dutyNo, dutyDay) {\n CrewRouteFactory.removeFlightTraining(dutyNo, dutyDay);\n setupView();\n $route.reload();\n }\n\n function removePendingGDEntry(groundDuty) {\n $scope.totalIncompleteGD.find(function (x) {\n return x.Id == groundDuty;\n }).isManualEntry = false;\n GroundDutyFactory.removeGroundDuty(groundDuty);\n return $scope.totalIncompleteGD;\n }\n\n function removePendingFlightEntry(dutyNo, dutyDay) {\n $scope.totalIncompleteFlightDuties.find(function (x) {\n return x.FlightId == dutyNo;\n }).isManualEntry = false;\n return $scope.totalIncompleteFlightDuties;\n }\n /**\r\n * Open Synch Modal\r\n * @memberof CalendarCtrl\r\n */\n\n\n function openSynch() {\n //store last time the sync dialog was displayed\n SyncLogFactory.setLastShow();\n openSynchModal();\n }\n\n function openSynchModal() {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgSynch.html',\n controller: 'SynchCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false\n });\n modalInstance.result.then(function (synchresult) {\n //refresh the view after a successful sync\n if (!synchresult == 'cancel') {\n $scope.setupView(true);\n }\n }, function () {});\n }\n\n function openMandatoryModal() {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgMandatory.html',\n controller: 'MandatoryModalCtrl',\n size: 'md',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n mandatoryUnread: $scope.mandatoryUnread\n }\n });\n }\n /**\r\n * Open the \"Add a flight\" Modal\r\n * @memberof CalendarCtrl\r\n */\n\n\n function addFlight() {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgAddFlight.html',\n controller: 'AddFlightCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false\n });\n }\n /**\r\n * Open the \"Search Ground Duties\" Modal\r\n * @memberof CalendarCtrl\r\n */\n\n\n function searchPastGroundDuties() {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgSearchGroundDuties.html',\n controller: 'SearchPastGDCtrl',\n size: 'md',\n backdrop: 'static',\n keyboard: false\n });\n }\n\n function acknowledge() {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgAcknowledgeChanges.html',\n controller: 'AcknowledgeModalCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false\n });\n }\n /**\r\n * Gets showExpiriesAlert value\r\n * @memberof calendarNotifications\r\n */\n\n\n function showExpiriesAlertCalendar() {\n return ExpiriesFactory.showExpiriesAlert();\n }\n /**\r\n * Gets showSubmissionDeadlineAlert value\r\n * @memberof calendarNotifications\r\n */\n\n\n function showSubmissionDeadlineAlertCalendar() {\n return RequestFactory.showSubmissionDeadlineAlert();\n }\n\n function showCheckInAction() {\n var retVal = false;\n var checkInInfo = CheckInFactory.getCheckInInfoFromStorage();\n\n if (checkInInfo && checkInInfo.AimsId > 0) {\n var now = moment.utc(); //Fetch FROM\n //Convert from Date UTC to Moment UTC\n\n var std = moment.utc(checkInInfo.STD);\n var minFetchTime = moment(std).add(-2, 'hours'); //Fetch UNTIL \n\n var maxFetchTime = moment(std).add(10, 'minutes');\n var isAfter = now.isAfter(minFetchTime);\n var isBefore = now.isBefore(maxFetchTime);\n\n if (isAfter && isBefore) {\n retVal = true;\n } //console.log({\"isAfter\":isAfter, \"isBefore\": isBefore, \"now\":now, \"std\":std, \"minFetchTime\":minFetchTime,\"maxFetchTime\":maxFetchTime});\n\n }\n\n return retVal;\n }\n\n function preparePasswordExpiryData() {\n //update PasswordExpiry scope:\n var user = UserFactory.getUser();\n\n if (user && user.passwordLastChangeDate) {\n var today = new Date();\n var lastChangeDate = new Date(user.passwordLastChangeDate);\n var expirationDate = lastChangeDate.AddDays(90); // how many days until duty date\n\n var diffDays = Date.DifferenceInDays(today.trimTime(), expirationDate.trimTime());\n $scope.passwordExpiry = {\n showAlert: diffDays && diffDays <= 14,\n lastChange: lastChangeDate,\n daysLeft: diffDays\n };\n }\n }\n /**\r\n * Shows the bootbox for schedule acknowledge reminder\r\n * @memberof calendarNotifications\r\n */\n\n\n function showReminderModal() {\n var _showScheduleChangesReminder = ScheduleAcknowledgeFactory.showScheduleChangesModal();\n\n var _showExpiriesReminder = ExpiriesFactory.showExpiriesModal();\n\n var _showSubmissionDeadlineReminder = RequestFactory.showSubmissionDeadlineModal();\n\n if (_showScheduleChangesReminder || _showExpiriesReminder || _showSubmissionDeadlineReminder) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgReminderModal.html',\n controller: 'ReminderModalCtrl',\n size: 'md',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n showScheduleChangesReminder: function showScheduleChangesReminder() {\n return _showScheduleChangesReminder;\n },\n showExpiriesReminder: function showExpiriesReminder() {\n return _showExpiriesReminder;\n },\n showSubmissionDeadlineReminder: function showSubmissionDeadlineReminder() {\n return _showSubmissionDeadlineReminder;\n }\n }\n });\n }\n }\n /**\r\n * Open Check in Modal\r\n * @memberof CalendarCtrl\r\n */\n\n\n function openCheckInModal() {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgCheckIn.html',\n controller: 'CheckInModalCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false\n });\n }\n /**\r\n * Redirect to flight Info\r\n * @memberof CalendarCtrl\r\n */\n\n\n function gotoFlightInfo(FlightId) {\n $location.path('/flightinfo/' + FlightId);\n }\n /**\r\n * Redirect to groundDuty Info\r\n * @memberof CalendarCtrl\r\n */\n\n\n function gotoGroundDutyInfo(GroundDutyId) {\n $location.path('/groundDuty/' + GroundDutyId);\n }\n /**\r\n * Redirect to crewRoute Info\r\n * @memberof CalendarCtrl\r\n */\n\n\n function gotoCrewRouteInfo(dutyNo, dutyDay) {\n $location.path('/crewRoute/' + dutyNo + '/' + dutyDay);\n }\n /**\r\n * Redirect to crewRoute Info\r\n * @memberof CalendarCtrl\r\n */\n\n\n function gotoCrewRouteInfo(dutyNo, dutyDay) {\n $location.path('/crewRoute/' + dutyNo + '/' + dutyDay);\n }\n /**\r\n * Redirect to Library Info with filter enabled\r\n * @memberof CalendarCtrl\r\n */\n\n\n function gotoUnreadMemos() {\n $location.path('/memos/unread');\n }\n /**\r\n * Redirect to messages\r\n * @memberof CalendarCtrl\r\n */\n\n\n function gotoMessages() {\n $location.path('/messages/');\n }\n /**\r\n * Redirect to leaves\r\n * @memberof CalendarCtrl\r\n */\n\n\n function gotoLeaves() {\n $location.path('/leaverequest/');\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('FlightFactory', FlightFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightFactory\r\n * @description \r\n * Add, Update, Delete and Get Flights \r\n * @ngInject\r\n */\n\n function FlightFactory($log, $filter, localStorageMD5Service, UserFactory, CabinReportLocalEditFactory, ServerCabinReportFactory, FlightCrewMemberFactory, MessageFactory, liveVersion, GenericService, SyncLogFactory) {\n var daysThatAFlightIsConsideredTooOld = -20;\n /**\r\n * Initialize the Flight\r\n * @memberof FlightFactory\r\n */\n\n function Flight() {\n this.AcTailNo = null;\n this.AcType = null;\n this.Category = null;\n this.CrewAimsId = null;\n this.Departure = null;\n this.Arrival = null;\n this.FlightAimsId = null;\n this.FlightId = null;\n this.FlightDate = null;\n this.FlightNo = null;\n this.IsDHC = null;\n this.Position = null; //v1.1 added pax and dep/arr details\n\n this.BookedC = null;\n this.BookedY = null;\n this.BookedInf = null;\n this.BookedPad = null;\n this.BookedChld = null;\n this.ActualC = null;\n this.ActualY = null;\n this.ActualInf = null;\n this.ActualPad = null;\n this.ActualChld = null;\n this.DepartureICAO = null;\n this.DepartureCountry = null;\n this.DepartureName = null;\n this.ArrivalICAO = null;\n this.ArrivalCountry = null;\n this.ArrivalName = null;\n this.ScheduledDeparture = null;\n this.Status = null;\n this.LineStatus = null;\n this.LineStatusDescr = null;\n this.LocalReportId = null;\n this.ServerReportLink = null;\n this.ScheduledDepartureDateUTC = null;\n this.ScheduledDepartureTimeUTC = null;\n this.LocalReportHasNothingToReport = false;\n this.ServerReportHasNothingToReport = false;\n this.IsLocal = false;\n this.cabinReports = [];\n this.cabinReportStatusDescr = '';\n this.crew = new Array(); //new fields\n\n this.DepartureGate = null;\n this.DepartureTimezone = null;\n this.ArrivalTimezone = null;\n this.CallSign = null;\n this.ScheduledArrival = null;\n this.messages = null;\n this.assessment = null;\n this.Route = null;\n this.DutyDate = null;\n this.FlightsFilters = [];\n this.ETA = null;\n this.IsScheduleChanged = false; //zones\n\n this.Zones = []; //\n\n this.AircraftDifferences = [];\n this.GetId = GetId;\n this.getRoute = getRoute;\n this.getDescription = getDescription;\n this.getSeniorAttendantsCount = getSeniorAttendantsCount; //TODO REMOVE CHECK VALIDITY WITH NEW VIEW\n\n this.initializeCabinReportStatus = initializeCabinReportStatus;\n this.getCabinReportStatusDescr = getCabinReportStatusDescr;\n this.getServerCabinReportForUser = getServerCabinReportForUser;\n this.getServerCabinReportsByAnotherUser = getServerCabinReportsByAnotherUser;\n this.initialize = initialize;\n }\n\n var service = {\n getFlightsFromStorage: getFlightsFromStorage,\n getFlightFromTotalFlights: getFlightFromTotalFlights,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n getFlightsFromStorageAndCheckIfTooOld: getFlightsFromStorageAndCheckIfTooOld,\n setFlightsToStorage: setFlightsToStorage,\n storeFlightsWithReportsAndMessages: storeFlightsWithReportsAndMessages,\n getFlightFromStorage: getFlightFromStorage,\n getFlightsByRoute: getFlightsByRoute,\n getLocalFlightFromStorage: getLocalFlightFromStorage,\n createLocalFlight: createLocalFlight,\n saveLocalFlight: saveLocalFlight,\n getLocalFlightsAndMergeWithServerFlights: getLocalFlightsAndMergeWithServerFlights,\n updateFlightFromReport: updateFlightFromReport,\n updateFlight: updateFlight,\n mergeFlightInfo: mergeFlightInfo,\n markScheduleChangedFlights: markScheduleChangedFlights,\n initializeFlights: initializeFlights,\n getFlightsByDutyNo: getFlightsByDutyNo,\n getFlightsWithStoredReport: getFlightsWithStoredReport,\n getFlightsByFlightId: getFlightsByFlightId,\n insertFlightsWithPendingTrainings: insertFlightsWithPendingTrainings,\n getTheFirstAndTheLastFlightDates: getTheFirstAndTheLastFlightDates\n };\n var objType = 'flights';\n var objCallback = Flight; //Object Functions\n\n /**\r\n * Overide default get Id\r\n * @memberof FlightFactory\r\n * @returns {number} Id \r\n */\n\n function GetId() {\n return this.FlightId;\n }\n /**\r\n * Get flight's Route\r\n * @memberof FlightFactory\r\n * @returns {string} route \r\n */\n\n\n function getRoute() {\n if (this.Departure == null && this.Arrival == null) return '-null-';else return (this.Departure || '?') + '-' + (this.Arrival || '?');\n }\n /**\r\n * Get flight's description\r\n * @memberof FlightFactory\r\n * @returns {string} description \r\n */\n\n\n function getDescription() {\n if (this.FlightNo == null && this.Departure == null && this.Arrival == null) return '-null-';else return (this.ScheduledDepartureDateUTC || '?') + ' ' + (this.FlightNo || '?') + ' ' + (this.Departure || '?') + '-' + (this.Arrival || '?');\n }\n /**\r\n * Get flight's Senior Attendants Count\r\n * @memberof FlightFactory\r\n * @returns {number} seniorAttendantsCount \r\n */\n\n\n function getSeniorAttendantsCount() {\n if (this.crew == null || this.crew.length == 0) return 0;\n var count = 0;\n var attendants = $filter('filter')(this.crew, {\n position: 'SA',\n isDHC: false\n });\n if (attendants != null) count = attendants.length;\n return count;\n }\n\n function insertFlightsWithPendingTrainings(flightsWithPendings) {\n if (flightsWithPendings) {\n var flights = getFlightsFromStorage();\n var flightIdsLS = flights.map(function (x) {\n return x.FlightId;\n });\n var flightsToInsert = flightsWithPendings.filter(function (f) {\n return !flightIdsLS.includes(f.FlightId);\n });\n var updatedFlightList = flights.concat(flightsToInsert);\n setFlightsToStorage(updatedFlightList);\n }\n }\n /**\r\n * Initialize Cabin report Status\r\n * @memberof FlightFactory\r\n */\n\n\n function initializeCabinReportStatus() {\n // load the user\n var user = UserFactory.getUser(); //Cannot file a report when a problem with the user or if the\n //person is DHC on that flight\n\n if (user == null || this.IsDHC != 0) {\n this.LineStatus = \"na\";\n return;\n } //not an SA? Normally not allowed to file a report\n //UNLESS there is no SA on board\n else if (this.Position != 'SA' && this.getSeniorAttendantsCount() > 0 && this.AcType != \"AT4\") {\n //console.debug('FA with ' + this.getSeniorAttendantsCount() + ' SA(s) on board!');\n this.LineStatus = \"na\";\n return;\n } // initialize to pending\n\n\n this.LineStatus = \"pending\"; // check if there is a local edit report or a server report for this\n // flight\n\n var serverReportForThisUser = this.getServerCabinReportForUser(user.aimsId);\n var serverReportsByAnotherUser = this.getServerCabinReportsByAnotherUser(user.aimsId);\n var hasServerReportForThisUser = serverReportForThisUser != null;\n var hasServerReportsByAnotherUser = serverReportsByAnotherUser.length > 0;\n var localReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(this.FlightId);\n this.LocalReportId = null;\n this.ServerReportLink = null; // if there is a local copy of the report\n\n if (localReport != null) {\n this.LocalReportId = localReport.ReportGuid;\n this.LocalReportHasNothingToReport = localReport.NothingToReport;\n\n if (localReport.Status === 'draft') {\n if (hasServerReportsByAnotherUser) this.LineStatus = \"draftotheruser\";else this.LineStatus = \"draft\";\n } else if (localReport.Status === 'completed') {\n if (hasServerReportsByAnotherUser) this.LineStatus = \"completedotheruser\";else this.LineStatus = \"completed\";\n } else if (localReport.Status === 'synched') {\n if (hasServerReportsByAnotherUser) this.LineStatus = \"synchedotheruser\";else this.LineStatus = \"synched\";\n } else {\n if (hasServerReportsByAnotherUser) this.LineStatus = \"draftotheruser\";else this.LineStatus = \"draft\";\n }\n } else {\n // if there is a server report by this and by another user\n if (hasServerReportForThisUser && hasServerReportsByAnotherUser) {\n this.LineStatus = \"stored+otheruser\"; // Something if this or any other user has something to\n // report\n\n this.ServerReportHasNothingToReport = serverReportForThisUser.ReportedItems == 0;\n\n if (this.ServerReportHasNothingToReport) {\n // if nothing to report by this user, check if any other\n // user has something to report\n for (var i = 0; i < serverReportsByAnotherUser.length; i++) {\n if (serverReportsByAnotherUser[i].ReportedItems > 0) {\n this.ServerReportHasNothingToReport = false;\n break;\n }\n }\n }\n } // if there is a server report for another user\n else if (hasServerReportsByAnotherUser) {\n this.LineStatus = \"storedotheruser\";\n this.ServerReportHasNothingToReport = true;\n\n for (var i = 0; i < serverReportsByAnotherUser.length; i++) {\n if (serverReportsByAnotherUser[i].ReportedItems > 0) {\n this.ServerReportHasNothingToReport = false;\n break;\n }\n }\n } // if there is a server report for only this user\n else if (hasServerReportForThisUser) {\n this.LineStatus = \"stored\";\n this.ServerReportHasNothingToReport = serverReportForThisUser.ReportedItems == 0;\n } // no server report\n else {\n this.LocalReportId = \"new\"; // no server report found for this user, status is pending\n\n if (new Date(this.ScheduledDeparture) < new Date()) {\n this.LineStatus = \"pendingoverdue\";\n } else {\n this.LineStatus = \"pending\";\n }\n }\n }\n }\n /**\r\n * Get Cabin Report Status Descr\r\n * @memberof FlightFactory\r\n * @returns {string} description \r\n */\n\n\n function getCabinReportStatusDescr() {\n if (this.LineStatus === 'na') return \"n/a\";else if (this.LineStatus === 'pending') return \"Pending\";else if (this.LineStatus === 'pendingoverdue') return \"Pending\";else if (this.LineStatus === 'draft') return \"Draft\";else if (this.LineStatus === 'completed') return \"Completed\";else if (this.LineStatus === 'synched') return \"Synched\";else if (this.LineStatus === 'draftotheruser') return \"Draft +\";else if (this.LineStatus === 'completedotheruser') return \"Completed +\";else if (this.LineStatus === 'synchedotheruser') return \"Synched +\";else if (this.LineStatus === 'stored') return \"Stored\";else if (this.LineStatus === 'storedotheruser') return \"Stored\";else if (this.LineStatus === 'stored+otheruser') return \"Stored +\";else return this.LineStatus;\n }\n /**\r\n * Get Server CabinReport For the selected User\r\n * @memberof FlightFactory\r\n * @param {number} userAimsId The user aims Id\r\n * @return {object} cabinReport \r\n */\n\n\n function getServerCabinReportForUser(userAimsId) {\n if (this.cabinReports == null) return null;\n var result = null;\n\n for (var i = 0; i < this.cabinReports.length; i++) {\n if (this.cabinReports[i] != null) {\n if (this.cabinReports[i].AuthorAimsId == userAimsId) {\n result = this.cabinReports[i];\n break;\n }\n }\n }\n\n return result;\n }\n /**\r\n * Get Server CabinReport For others than the selected User\r\n * @memberof FlightFactory\r\n * @param {number} userAimsId The user aims Id\r\n * @return {object} cabinReport \r\n */\n\n\n function getServerCabinReportsByAnotherUser(userAimsId) {\n if (this.cabinReports == null) return new Array();\n var result = new Array();\n\n for (var i = 0; i < this.cabinReports.length; i++) {\n if (this.cabinReports[i] != null) {\n if (this.cabinReports[i].AuthorAimsId != userAimsId) {\n result.push(this.cabinReports[i]);\n }\n }\n }\n\n return result;\n }\n /**\r\n * Initialize Cabin Report\r\n * @memberof FlightFactory\r\n */\n\n\n function initialize() {\n try {\n // SD date/time\n if (this.ScheduledDeparture != null) {\n var STD = this.ScheduledDeparture;\n if (STD.indexOf('Z') < 0) STD += 'Z';\n STD = new moment(STD);\n STD = new Date(STD);\n STD = STD.toUTC();\n this.ScheduledDepartureDateUTC = STD.toString('yyyy-MM-dd');\n this.ScheduledDepartureTimeUTC = STD.toString('HH:mm');\n } // initialize the cabin report status field\n\n\n this.initializeCabinReportStatus(); // initialize css classes for display\n\n this.cabinReportStatusDescr = this.getCabinReportStatusDescr();\n } catch (ex) {\n $log.error(\"initialize failed: \" + ex.message);\n }\n } //Factory Functions\n\n /**\r\n * Extend Object from the default Flight Object\r\n * @memberof FlightFactory\r\n * @param {Object} obj a Flight\r\n * @returns {Object} Flight\r\n */\n\n\n function fromObject(obj) {\n if (obj == null) return null;\n var flight = new Flight();\n angular.extend(flight, obj);\n if (obj.crew == null) obj.crew = [];\n flight.crew = new Array();\n\n for (var j = 0; j < obj.crew.length; j++) {\n flight.crew.push(FlightCrewMemberFactory.fromObject(obj.crew[j]));\n }\n\n return flight;\n }\n\n ;\n /**\r\n * Extend an array of Objects from the default flight Object\r\n * @memberof FlightFactory\r\n * @param {Array} objList an Array Of flights\r\n * @returns {Array} flights\r\n */\n\n function fromObjectList(objList) {\n if (objList == null) return [];\n var arrayLength = objList.length;\n var flights = new Array();\n\n for (var i = 0; i < arrayLength; i++) {\n var flight = new Flight();\n angular.extend(flight, objList[i]);\n if (objList[i].crew == null) objList[i].crew = [];\n flights.push(flight);\n }\n\n return flights;\n }\n\n ;\n /**\r\n * Returns all the flights from storage\r\n * @memberof FlightFactory\r\n * @returns {Array} flights\r\n */\n\n function getFlightsFromStorage() {\n var objects = localStorageMD5Service.get(objType);\n return fromObjectList(objects);\n }\n /**\r\n * Returns the flights from local storage only if they are recent\r\n * @memberof FlightFactory\r\n * @returns {Array} flights\r\n */\n\n\n function getFlightsFromStorageAndCheckIfTooOld() {\n var result = getFlightsFromStorage();\n if (result == null) return null;\n var dataIsRecent = false;\n var arrayLength = result.length; // loop all flights and break if a flight in the last 10 days is found\n\n for (var i = 0; i < arrayLength; i++) {\n if (Date.today().add(daysThatAFlightIsConsideredTooOld).days().toUTC().isBefore(new Date(result[i].ScheduledDeparture).toUTC().trimTime())) {\n dataIsRecent = true;\n break;\n }\n }\n\n if (dataIsRecent == true || !liveVersion) return result;else return null;\n }\n /**\r\n * Set flights to storage\r\n * @memberof FlightFactory\r\n * @returns {Array} flights\r\n */\n\n\n function setFlightsToStorage(flights) {\n for (var i = 0; i < flights.length; i++) {\n if (flights[i].FlightId == undefined || flights[i].FlightId == null) {\n flights[i].FlightId = guid();\n }\n }\n\n localStorageMD5Service.set('flights', flights);\n }\n /**\r\n * Initialize flights and save them\r\n * @memberof FlightFactory\r\n */\n\n\n function initializeFlights() {\n var objList = localStorageMD5Service.get(objType);\n if (objList == null) return null;\n var arrayLength = objList.length;\n var flights = new Array();\n\n for (var i = 0; i < arrayLength; i++) {\n var flight = new Flight();\n angular.extend(flight, objList[i]);\n if (objList[i].crew == null) objList[i].crew = [];\n flight.crew = new Array();\n\n for (var j = 0; j < objList[i].crew.length; j++) {\n flight.crew.push(FlightCrewMemberFactory.fromObject(objList[i].crew[j]));\n }\n\n flight.initialize();\n flights.push(flight);\n }\n\n localStorageMD5Service.set('flights', flights);\n }\n /**\r\n * Store Flights With Reports And Messages\r\n * @memberof FlightFactory\r\n * @param {Array} flights \r\n * @param {Array} cabinReports\r\n * @param {Array} messages\r\n */\n\n\n function storeFlightsWithReportsAndMessages(flights, cabinReports, messages) {\n var flightsX = fromObjectList(flights);\n var cabinReportsX = ServerCabinReportFactory.fromObjectList(cabinReports);\n var messagesX = MessageFactory.fromObjectList(messages);\n\n if (flightsX && flightsX instanceof Array && flightsX.length > 0 && (cabinReportsX || messagesX)) {\n // loop all flights\n var user = UserFactory.getUser();\n var f, pr, me;\n\n for (var fi = 0; fi < flightsX.length; fi++) {\n f = flightsX[fi]; // find cabin reports for this flight\n\n f.cabinReports = [];\n f.messages = [];\n\n if (cabinReportsX && cabinReportsX instanceof Array && cabinReportsX.length > 0) {\n for (var pri = 0; pri < cabinReportsX.length; pri++) {\n pr = cabinReportsX[pri];\n\n if (pr.FlightId != null && pr.FlightId == f.FlightId) {\n if (pr.AuthorAimsId == f.CrewAimsId) {\n pr.Source = ServerCabinReportFactory.constSourceStoredOwn;\n f.cabinReports.push(pr);\n } else {\n pr.Source = ServerCabinReportFactory.constSourceStoredOther;\n f.cabinReports.push(pr);\n }\n }\n }\n }\n\n if (messagesX && messagesX instanceof Array && messagesX.length > 0) {\n for (var mi = 0; mi < messagesX.length; mi++) {\n me = messagesX[mi];\n var vf = moment.utc(me.ValidFrom);\n var vt = moment.utc(me.ValidTo);\n\n if (moment.utc(f.FlightDate).isBetween(vf, vt, undefined, '[]')) {\n if (me.QueryType.trim() == 'Country' && (me.Country.trim() == f.ArrivalCountry || me.Country.trim() == f.DepartureCountry)) {\n f.messages.push(me.Id);\n } else if (me.QueryType.trim() == 'FlightNo' && me.FlightNo == f.FlightNo) {\n f.messages.push(me.Id);\n } else if (me.QueryType.trim() == 'Airports') {\n if (me.FlightDirection == 'DEP' && me.AirportA == f.Departure && me.AirportB == f.Arrival) {\n f.messages.push(me.Id);\n } else if (me.FlightDirection == 'ARR' && me.AirportB == f.Departure && me.AirportA == f.Arrival) {\n f.messages.push(me.Id);\n } else if (me.FlightDirection == 'ANY' && (me.AirportA == f.Departure && me.AirportB == f.Arrival || me.AirportB == f.Departure && me.AirportA == f.Arrival)) {\n f.messages.push(me.Id);\n }\n } else if (me.QueryType.trim() == 'Airport') {\n if (me.FlightDirection == 'DEP' && me.AirportA == f.Departure) {\n f.messages.push(me.Id);\n } else if (me.FlightDirection == 'ARR' && me.AirportA == f.Arrival) {\n f.messages.push(me.Id);\n } else if (me.FlightDirection == 'ANY' && (me.AirportA == f.Departure || me.AirportA == f.Arrival)) {\n f.messages.push(me.Id);\n }\n } else if (me.QueryType.trim() == 'Registration' && f.AcTailNo == me.Registration) {\n f.messages.push(me.Id);\n } else if (me.QueryType.trim() == 'AcType' && f.AcType == me.AcType) {\n f.messages.push(me.Id);\n }\n }\n }\n }\n\n f.initialize();\n }\n }\n\n localStorageMD5Service.set('flights', flightsX);\n }\n /**\r\n * Get Flight from local and storage flights\r\n * @memberof FlightFactory\r\n * @param {number} flightId \r\n * @return {object} flight\r\n */\n\n\n function getFlightFromTotalFlights(flightId) {\n var flight = getFlightFromStorage(flightId);\n\n if (!flight) {\n flight = getLocalFlightFromStorage(flightId);\n }\n\n return flight;\n }\n /**\r\n * Get Flight from storage flights\r\n * @memberof FlightFactory\r\n * @param {number} flightId \r\n * @return {object} flight\r\n */\n\n\n function getFlightFromStorage(flightId) {\n var objects = localStorageMD5Service.get(objType);\n if (objects == null) return null;\n var result = null;\n var arrayLength = objects.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (objects[i].FlightId == flightId) {\n result = objects[i];\n break;\n }\n }\n\n return fromObject(result);\n }\n /**\r\n * Get the Flights of the selected route\r\n * @memberof FlightFactory\r\n * @param {string} Route \r\n * @param {string} DutyDate \r\n * @return {array} flights\r\n */\n\n\n function getFlightsByRoute(Route, DutyDate) {\n var flights = getFlightsFromStorage();\n if (flights == null) return [];\n var result = [];\n var arrayLength = flights.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (flights[i].Route == Route && flights[i].DutyDate == DutyDate) {\n result.push(flights[i]);\n }\n }\n\n return result;\n }\n /**\r\n * create a local flight (Add flight button on main screen)\r\n * @memberof FlightFactory\r\n * @param {string} datetime \r\n * @param {string} number \r\n * @param {string} departure \r\n * @param {string} destination \r\n * @param {string} regno \r\n * @param {string} actype \r\n * @return {object} flight\r\n */\n\n\n function createLocalFlight(datetime, number, departure, destination, regno, actype) {\n var user = UserFactory.getUser();\n if (user == null) return null;\n var result = new Flight();\n result.AcTailNo = regno;\n result.AcType = actype;\n result.Category = '-';\n result.CrewAimsId = user.aimsId;\n result.Departure = departure;\n result.Arrival = destination;\n result.FlightAimsId = guid();\n result.FlightId = guid();\n result.FlightDate = datetime.toString('yyyy-MM-dd') + 'T' + datetime.toString('HH:mm:ss');\n ;\n result.FlightNo = number;\n result.IsDHC = 0;\n result.Position = user.position;\n result.ScheduledDeparture = datetime.toString('yyyy-MM-dd') + 'T' + datetime.toString('HH:mm:ss');\n result.Status = 'OK';\n result.IsLocal = true;\n result.initialize();\n return result;\n }\n /**\r\n * Save a local flight\r\n * @memberof FlightFactory\r\n * @param {object} flight\r\n */\n\n\n function saveLocalFlight(flight) {\n // get the local flights array from storage\n var localFlights = fromObjectList(localStorageMD5Service.get('localFlights'));\n if (localFlights == null) localFlights = new Array(); // find the current flight in the array (if present)\n\n var arrayLength = localFlights.length;\n var flightIndex = -1;\n\n for (var i = 0; i < arrayLength; i++) {\n if (localFlights[i].FlightId != null && localFlights[i].FlightId == flight.FlightId) {\n flightIndex = i;\n break;\n }\n } // add or update a copy of the current report\n\n\n if (flightIndex >= 0) localFlights[flightIndex] = flight;else localFlights.push(flight); // save\n\n localStorageMD5Service.set('localFlights', localFlights);\n }\n /**\r\n * merges the given flights with the stored local flights\r\n * @memberof FlightFactory\r\n * @param {array} serverFlights \r\n * @return {array} flights\r\n */\n\n\n function getLocalFlightsAndMergeWithServerFlights(serverFlights) {\n if (serverFlights == null) serverFlights = []; // get the local flights array from storage\n\n var localFlights = fromObjectList(localStorageMD5Service.get('localFlights'));\n if (localFlights == null) localFlights = []; // add the local flight to the given array\n\n var arrayLength = localFlights.length;\n\n for (var i = 0; i < arrayLength; i++) {\n localFlights[i].initialize();\n serverFlights.push(localFlights[i]);\n }\n\n return serverFlights;\n }\n /**\r\n * Get Flight from local flights\r\n * @memberof FlightFactory\r\n * @param {number} flightId \r\n * @return {object} flight\r\n */\n\n\n function getLocalFlightFromStorage(flightId) {\n var flight = GenericService.get(flightId, 'localFlights', objCallback);\n\n if (flight) {\n flight.initialize();\n }\n\n return fromObject(flight);\n }\n /**\r\n * Update Flight from report\r\n * @memberof FlightFactory\r\n * @param {object} report \r\n */\n\n\n function updateFlightFromReport(report) {\n var flight = getFlightFromStorage(report.FlightId);\n\n if (flight != null && flight != undefined) {\n var reportIndex;\n flight.AcTailNo = report.AcTailNo;\n flight.AcType = report.AcType;\n var allflights = getFlightsFromStorage();\n\n for (var i = 0; i < allflights.length; i++) {\n if (allflights[i].FlightId != null && allflights[i].FlightId == report.FlightId) {\n reportIndex = i;\n break;\n }\n }\n\n flight.initialize();\n allflights[reportIndex] = flight;\n setFlightsToStorage(allflights);\n }\n }\n /**\r\n * Update Flight \r\n * @memberof FlightFactory\r\n * @param {object} flight \r\n */\n\n\n function updateFlight(flight) {\n // get the flights array from storage\n var flights = getFlightsFromStorage(); // find the current flight in the array (if present)\n\n var arrayLength = flights.length;\n var flightIndex = -1;\n\n for (var i = 0; i < arrayLength; i++) {\n if (flights[i].FlightId != null && flights[i].FlightId == flight.FlightId) {\n flightIndex = i;\n break;\n }\n } //Add or update a copy of the current report\n\n\n if (flightIndex >= 0) flights[flightIndex] = flight;else flights.push(flight); //Save\n\n localStorageMD5Service.set('flights', flights);\n }\n /**\r\n * mark Schedule Changed Flights by comparing flights from new and old data\r\n * @memberof FlightFactory\r\n * @param {object} newFlights \r\n * @param {object} oldFlights\r\n * @return {object} newFlights \r\n */\n\n\n function markScheduleChangedFlights(newFlights, oldFlights) {\n var lastScheduleDate = SyncLogFactory.getLastScheduleDate(); //if there are no old flights or no last schedule date\n\n if (oldFlights && lastScheduleDate) {\n //loop all new flights\n var exists;\n\n for (var i = 0; i < newFlights.length; i++) {\n //loop all old flights\n exists = false;\n\n for (var j = 0; j < oldFlights.length; j++) {\n if (newFlights[i].FlightNo == oldFlights[j].FlightNo && newFlights[i].FlightNo == oldFlights[j].FlightNo && newFlights[i].FlightDate == oldFlights[j].FlightDate && newFlights[i].Departure == oldFlights[j].Departure) {\n exists = true;\n break;\n }\n } //check if flight is newly added and is before the last schedule date\n\n\n var flightDate = new Date(newFlights[i].FlightDate);\n\n if (!exists && flightDate.getTime() <= lastScheduleDate) {\n newFlights[i].IsScheduleChanged = true;\n }\n }\n }\n\n return newFlights;\n } //factory functions\n\n /**\r\n * Update Passenger information\r\n * @memberof FlightFactory\r\n * @param {object} flightInfo The flight informations \r\n */\n\n\n function mergeFlightInfo(flightInfo, showPaxNames) {\n if (flightInfo) {\n var currentFlightInfo = GenericService.get(flightInfo.FlightId, objType, objCallback);\n currentFlightInfo.CrewAimsId = flightInfo.CrewAimsId;\n currentFlightInfo.DutyDate = flightInfo.DutyDate;\n currentFlightInfo.Route = flightInfo.Route;\n currentFlightInfo.FlightId = flightInfo.FlightId;\n currentFlightInfo.FlightAimsId = flightInfo.FlightAimsId;\n currentFlightInfo.FlightDate = flightInfo.FlightDate;\n currentFlightInfo.FlightNo = flightInfo.FlightNo;\n currentFlightInfo.Departure = flightInfo.Departure;\n currentFlightInfo.Arrival = flightInfo.Arrival;\n currentFlightInfo.AcType = flightInfo.AcType;\n currentFlightInfo.AcTailNo = flightInfo.AcTailNo;\n currentFlightInfo.ScheduledDeparture = flightInfo.ScheduledDeparture;\n currentFlightInfo.ScheduledArrival = flightInfo.ScheduledArrival;\n currentFlightInfo.BookedC = flightInfo.BookedC;\n currentFlightInfo.BookedY = flightInfo.BookedY;\n currentFlightInfo.BookedInf = flightInfo.BookedInf;\n currentFlightInfo.BookedPad = flightInfo.BookedPad;\n currentFlightInfo.BookedChld = flightInfo.BookedChld;\n currentFlightInfo.ActualC = flightInfo.ActualC;\n currentFlightInfo.ActualY = flightInfo.ActualY;\n currentFlightInfo.ActualInf = flightInfo.ActualInf;\n currentFlightInfo.ActualPad = flightInfo.ActualPad;\n currentFlightInfo.ActualChld = flightInfo.ActualChld;\n currentFlightInfo.Category = flightInfo.Category;\n currentFlightInfo.Status = flightInfo.Status;\n currentFlightInfo.Position = flightInfo.Position;\n currentFlightInfo.IsDHC = flightInfo.IsDHC;\n currentFlightInfo.CallSign = flightInfo.CallSign;\n currentFlightInfo.DepartureGate = flightInfo.DepartureGate;\n currentFlightInfo.DepartureStand = flightInfo.DepartureStand;\n currentFlightInfo.ArrivalStand = flightInfo.ArrivalStand;\n currentFlightInfo.DepartureICAO = flightInfo.DepartureICAO;\n currentFlightInfo.DepartureName = flightInfo.DepartureName;\n currentFlightInfo.DepartureCountry = flightInfo.DepartureCountry;\n currentFlightInfo.ArrivalICAO = flightInfo.ArrivalICAO;\n currentFlightInfo.ArrivalName = flightInfo.ArrivalName;\n currentFlightInfo.ArrivalCountry = flightInfo.ArrivalCountry;\n currentFlightInfo.DepartureTimezone = flightInfo.DepartureTimezone;\n currentFlightInfo.ArrivalTimezone = flightInfo.ArrivalTimezone;\n currentFlightInfo.DepartureSchengen = flightInfo.DepartureSchengen;\n currentFlightInfo.ArrivalSchengen = flightInfo.ArrivalSchengen;\n currentFlightInfo.DepartureEU = flightInfo.DepartureEU;\n currentFlightInfo.ArrivalEU = flightInfo.ArrivalEU;\n currentFlightInfo.ETD = flightInfo.ETD;\n currentFlightInfo.ATD = flightInfo.ATD;\n currentFlightInfo.ETA = flightInfo.ETA;\n currentFlightInfo.ATA = flightInfo.ATA;\n currentFlightInfo.CTOT = flightInfo.CTOT;\n currentFlightInfo.DepartureCountryISO = flightInfo.DepartureCountryISO;\n currentFlightInfo.ArrivalCountryISO = flightInfo.ArrivalCountryISO;\n currentFlightInfo.crew = flightInfo.crew;\n currentFlightInfo.Zones = flightInfo.Zones;\n currentFlightInfo.showPaxNames = showPaxNames;\n GenericService.save(currentFlightInfo, objType, objCallback);\n }\n }\n /**\r\n * Get Flights of a Crew Route\r\n * @memberof FlightFactory\r\n * @param {number} dutyNo \r\n * @param {string} dutyDay\r\n * @return {array} flights\r\n */\n\n\n function getFlightsByDutyNo(dutyNo, dutyDay) {\n var flights = getFlightsFromStorage();\n if (flights == null) return [];\n var result = [];\n var arrayLength = flights.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (flights[i].DutyNo == dutyNo && flights[i].DutyDay == dutyDay) {\n result.push(flights[i]);\n }\n }\n\n return result;\n }\n /**\r\n * Get Flights of a Crew Route using a flightId\r\n * @memberof FlightFactory\r\n * @param {number} flightId \r\n * @return {array} flights\r\n */\n\n\n function getFlightsByFlightId(flightId) {\n var result = [];\n var flight = getFlightFromStorage(flightId);\n var flights = getFlightsFromStorage();\n\n if (flight != null) {\n for (var i = 0; i < flights.length; i++) {\n if (flights[i].DutyNo == flight.DutyNo && flights[i].DutyDay == flight.DutyDay) {\n result.push(flights[i]);\n }\n }\n }\n\n return result;\n }\n /**\r\n * Get Flights with report status \"Stored\"\r\n * @memberof FlightFactory\r\n * @return {array} flights\r\n */\n\n\n function getFlightsWithStoredReport() {\n var flights = getFlightsFromStorage();\n if (flights == null) return [];\n var result = [];\n var arrayLength = flights.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (flights[i].cabinReportStatusDescr == \"Stored\") {\n result.push(flights[i]);\n }\n }\n\n return result;\n }\n\n function getTheFirstAndTheLastFlightDates() {\n var flights = getFlightsFromStorage();\n\n var parseDate = function parseDate(dateString) {\n return new Date(dateString);\n };\n\n var firstFlightDate = null;\n var lastFlightDate = null;\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = flights[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var obj = _step.value;\n //const currentDate = new Date(obj.FlightDate);\n var currentDate = parseDate(obj.FlightDate);\n\n if (!firstFlightDate || currentDate < firstFlightDate) {\n firstFlightDate = currentDate;\n }\n\n if (!lastFlightDate || currentDate > lastFlightDate) {\n lastFlightDate = currentDate;\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator[\"return\"] != null) {\n _iterator[\"return\"]();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return {\n firstDate: firstFlightDate,\n lastDate: lastFlightDate\n };\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('FlightCrewMemberFactory', FlightCrewMemberFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightCrewMemberFactory\r\n * @description \r\n * Add, Update, Delete and Get Flight Crew Members.\r\n * @ngInject\r\n */\n\n function FlightCrewMemberFactory(GenericModalFactory) {\n /**\r\n * Initialize the FlightCrewMember\r\n * @memberof FlightCrewMemberFactory\r\n */\n function FlightCrewMember() {\n this.aimsId = null;\n this.id = null;\n this.isDHC = null;\n this.name = null;\n this.position = null;\n this.sex = null;\n this.shortname = null;\n }\n\n var service = {\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n deleteFromList: deleteFromList\n };\n /**\r\n * Extend Object from the default FlightCrewMember Object\r\n * @memberof FlightCrewMemberFactory\r\n * @param {Object} obj a FlightCrewMember\r\n * @returns {Object} FlightCrewMember\r\n */\n\n function fromObject(obj) {\n return GenericModalFactory.fromObject(obj, FlightCrewMember);\n }\n /**\r\n * Delete object from given list and update it\r\n * @memberof FlightCrewMemberFactory\r\n * @param {object} obj a Flight Crew Member\r\n * @param {Array} objList an Array Of Flight Crew Member\r\n * @returns {Array} FlightCrewMembers\r\n *\r\n */\n\n\n function deleteFromList(obj, objList) {\n return GenericModalFactory.deleteFromList(obj, objList);\n }\n /**\r\n * Extend an array of Objects from the default Flight Crew Member Object\r\n * @memberof FlightCrewMemberFactory\r\n * @param {Array} objList an Array Of Flight Crew Member\r\n * @returns {Array} FlightCrewMembers\r\n */\n\n\n function fromObjectList(objList) {\n return GenericModalFactory.fromObjectList(objList, FlightCrewMember);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('ReminderModalCtrl', ReminderModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ReminderModalCtrl\r\n * @description \r\n * Warning Modal about acknowledge schedule changes and medical & passport expiries\r\n * @ngInject\r\n */\n\n function ReminderModalCtrl(showExpiriesReminder, showSubmissionDeadlineReminder, showScheduleChangesReminder, ExpiriesFactory, RequestFactory, ScheduleAcknowledgeFactory, $scope, $uibModalInstance) {\n $scope.cancel = cancel; //from parent view:\n\n $scope.showScheduleChangesReminder = showScheduleChangesReminder;\n $scope.showExpiriesReminder = showExpiriesReminder;\n $scope.showSubmissionDeadlineReminder = showSubmissionDeadlineReminder;\n $scope.expiryList = ExpiriesFactory.getCrewExpiriesFromStorage();\n $scope.submissionDeadline = RequestFactory.getSubmissionDeadlineDateFromStorage();\n $scope.daysDiff = daysDiff;\n /**\r\n * Calculates days left\r\n * @return {string} usage\r\n */\n\n function daysDiff(date) {\n var today = moment().startOf('day');\n var expiryDate = moment(date);\n return expiryDate.diff(today, 'days');\n }\n /**\r\n * Closes modal\r\n * @memberof ProposalInfoModalCtr\r\n */\n\n\n function cancel() {\n if ($scope.showScheduleChangesReminder) {\n ScheduleAcknowledgeFactory.updateShowScheduleChangesModal(false);\n }\n\n if ($scope.showExpiriesReminder) {\n ExpiriesFactory.updateShowExpiriesModal(false);\n }\n\n if ($scope.showSubmissionDeadlineReminder) {\n RequestFactory.updateShowSubmissionDeadlineModal(false);\n }\n\n $uibModalInstance.close('cancel');\n }\n }\n})();\n\"use strict\";\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('EventFormModalCtrl', EventFormModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name EventFormModalCtrl\r\n * @description \r\n * Flight Fervice Event Form Modal\r\n * @ngInject\r\n */\n\n function EventFormModalCtrl($scope, eventType, $uibModalInstance, FlightServiceEventsFactory) {\n $scope.eventType = _objectSpread({}, JSON.parse(JSON.stringify(eventType)));\n var defaultStart = $scope.eventType.event.StartTime ? moment($scope.eventType.event.StartTime) : null;\n var defaultEnd = $scope.eventType.event.EndTime ? moment($scope.eventType.event.EndTime) : null;\n $scope.cancel = cancel;\n $scope.close = close;\n $scope.submit = submit;\n $scope.startGetTime = startGetTime;\n $scope.endGetTime = endGetTime;\n $scope.resetStart = resetStart;\n $scope.resetEnd = resetEnd;\n $scope.clearRemarks = clearRemarks;\n $scope.requiredValueChanged = requiredValueChanged;\n $scope.showStart = defaultStart != null;\n $scope.showEnd = defaultEnd != null;\n $scope.showStartToggle = showStartToggle;\n $scope.showEndToggle = showEndToggle;\n $scope.showContent = 'eventForm';\n $scope.resultMessage = \"\";\n $scope.formValues = {};\n $scope.formValues.StartTime = $scope.eventType.event.StartTime ? moment($scope.eventType.event.StartTime) : null;\n $scope.formValues.EndTime = $scope.eventType.event.EndTime ? moment($scope.eventType.event.EndTime) : null;\n $scope.formValues.notRequired = $scope.eventType.event.NotRequired;\n $scope.formValues.showTimePickers = !$scope.formValues.notRequired;\n\n function startGetTime() {\n $scope.formValues.StartTime = getNowValue();\n }\n\n function endGetTime() {\n $scope.formValues.EndTime = getNowValue();\n }\n\n function resetStart() {\n $scope.formValues.StartTime = defaultStart;\n }\n\n function resetEnd() {\n $scope.formValues.EndTime = defaultEnd;\n }\n\n function clearRemarks() {\n $scope.eventType.event.Remarks = '';\n }\n\n function showStartToggle() {\n $scope.showStart = !$scope.showStart;\n\n if (!$scope.showStart) {\n resetStart();\n }\n }\n\n function showEndToggle() {\n $scope.showEnd = !$scope.showEnd;\n\n if (!$scope.showEnd) {\n resetEnd();\n } else {\n $scope.showStart = true;\n }\n }\n\n function requiredValueChanged() {\n $scope.formValues.notRequired = !$scope.formValues.notRequired;\n\n if ($scope.formValues.notRequired) {\n $scope.formValues.showTimePickers = false;\n $scope.formValues.StartTime = null;\n $scope.formValues.EndTime = null;\n clearRemarks();\n } else {\n $scope.formValues.showTimePickers = true;\n }\n }\n\n function getNowValue() {\n var currentUtcTime = new Date().toUTC();\n return moment.utc(currentUtcTime).format();\n }\n /**\r\n * Close the modal\r\n */\n\n\n function cancel() {\n var doRefreshPanel = true;\n $uibModalInstance.close(doRefreshPanel);\n }\n\n function close() {\n var doRefreshPanel = true;\n $uibModalInstance.close(doRefreshPanel);\n }\n /**\r\n * Submit event\r\n */\n\n\n function submit() {\n $scope.showContent = \"loading\"; // UpdateTimes\n\n $scope.eventType.event.StartTime = $scope.formValues.StartTime !== null && $scope.formValues.StartTime !== undefined ? moment($scope.formValues.StartTime) : null;\n $scope.eventType.event.EndTime = $scope.formValues.EndTime !== null && $scope.formValues.EndTime !== undefined ? moment($scope.formValues.EndTime) : null;\n $scope.eventType.event.NotRequired = $scope.formValues.notRequired;\n FlightServiceEventsFactory.saveEvent($scope.eventType.event).then(function (res) {\n return handleSaveResponse(res);\n })[\"catch\"](function (res) {\n return SaveFailedCallBack(res);\n });\n }\n /**\r\n * Response success\r\n */\n\n\n function handleSaveResponse(results) {\n if (results && results.data && results.data.success && results.data.data && results.data.data.length > 0) {\n FlightServiceEventsFactory.setEventsForFlightId($scope.eventType.event.FlightId, results.data.data); //Success\n\n $scope.resultMessage = \"Success\";\n $scope.showContent = 'results';\n } else {\n //Failed\n $scope.resultMessage = \"Failed\";\n $scope.showContent = 'results';\n }\n }\n /**\r\n * Response failed\r\n */\n\n\n function SaveFailedCallBack() {\n $scope.resultMessage = \"Failed\";\n $scope.showContent = 'results';\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('flightServiceEvents', flightServiceEvents);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name flightServiceEvents\r\n * @restrict E\r\n * @description\r\n * Implementation of flightServiceEvents panel\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function flightServiceEvents(FlightServiceEventsFactory, $sce, $uibModal) {\n function link(scope, element, attributes) {\n //scope.save = save;\n scope.events = [];\n scope.eventTypes = [];\n scope.openEvent = openEvent;\n scope.isRefreshing = false;\n scope.refreshEvents = refreshEvents; //get from LS the events & the types\n\n getEventsNTypes(scope.flightId);\n\n function getEventsNTypes(flightId) {\n scope.showPanel = null;\n scope.eventTypes = FlightServiceEventsFactory.getEventTypes();\n scope.events = FlightServiceEventsFactory.getEventsByFlightIdFromLS(flightId); //Merge eventTypes and events using common Code property\n\n scope.eventTypes.forEach(function (type) {\n var eventInType = scope.events.filter(function (x) {\n return x.EventCode == type.Code;\n });\n\n if (eventInType[0]) {\n type.event = eventInType[0];\n } else {\n type.event = {\n FlightId: flightId,\n EventTypeId: type.Id,\n EventCode: type.Code,\n StartTime: null,\n EndTime: null,\n NotRequired: null,\n Remarks: null\n };\n }\n });\n }\n\n function refreshEvents() {\n scope.isRefreshing = true;\n\n if (scope.isOffline) {\n scope.showPanel = \"offline\";\n scope.isRefreshing = false;\n } else {\n FlightServiceEventsFactory.getEvents(scope.flightId).then(function (res) {\n return handleRefreshResponse(res);\n });\n }\n }\n\n function handleRefreshResponse(results) {\n if (results && results.data && results.data.success && results.data.data && results.data.data.length > 0) {\n FlightServiceEventsFactory.setEventsForFlightId(scope.flightId, results.data.data);\n getEventsNTypes(scope.flightId);\n }\n\n scope.isRefreshing = false;\n }\n /**\r\n * Open modal to see information for the selected Memo\r\n * @memberof memosByCategory\r\n * @param {object} eventType with event object\r\n */\n\n\n function openEvent(_eventType) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/FlightServiceEvents/dlgEventForm.html',\n controller: 'EventFormModalCtrl',\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n eventType: function eventType() {\n return _eventType;\n }\n }\n });\n modalInstance.result.then(function () {\n //dismiss event\n refreshEvents();\n }, function () {\n //close event\n refreshEvents();\n });\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/FlightServiceEvents/flightServiceEvents.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('FlightServiceEventsFactory', FlightServiceEventsFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightServiceEventsFactory\r\n * @description \r\n * Get selected flight info\r\n * @ngInject\r\n */\n\n function FlightServiceEventsFactory($http, apiUrl, GenericService) {\n var service = {\n setEventTypes: setEventTypes,\n setEventsForFlightId: setEventsForFlightId,\n getEventsFromLS: getEventsFromLS,\n getEventTypes: getEventTypes,\n getEventsByFlightIdFromLS: getEventsByFlightIdFromLS,\n getEvents: getEvents,\n saveEvent: saveEvent,\n cleanOldDataServiceEvents: cleanOldDataServiceEvents,\n upsertEvents: upsertEvents\n };\n /**\r\n * Initialize the EventType \r\n * @memberof FlightServiceEventsFactory\r\n */\n\n function EventType() {\n this.Id = null;\n this.Code = null;\n this.Title = null;\n this.Description = null;\n this.EnableStartTime = true;\n this.EnableEndTime = false;\n this.EnableNotRequired = false;\n this.AllowRemarks = false;\n }\n\n var objEventType = 'flightEventTypes';\n var objEventTypeCallback = EventType;\n /**\r\n * Save Event Types\r\n * @memberof FlightServiceEventsFactory\r\n * @param {Array} EventTypes\r\n */\n\n function setEventTypes(eventTypes) {\n GenericService.saveAll(eventTypes, objEventType);\n }\n /**\r\n * Get Event Types\r\n * @memberof FlightServiceEventsFactory\r\n * @returns {Array} EventTypes \r\n */\n\n\n function getEventTypes() {\n return GenericService.list(objEventType, objEventTypeCallback);\n }\n /**\r\n * Initialize the Event \r\n * @memberof FlightServiceEventsFactory\r\n */\n\n\n function Event() {\n this.FlightId = null;\n this.EventTypeId = null;\n this.EventCode = null;\n this.StartTime = null;\n this.EndTime = null;\n this.NotRequired = null;\n this.Remarks = null;\n this.LastUpdated = null;\n }\n\n var objEvent = 'flightEvents';\n var objEventCallback = Event;\n\n function getEventsFromLS() {\n return GenericService.list(objEvent, objEventCallback);\n }\n\n function getEventsByFlightIdFromLS(flightId) {\n var storedEvents = getEventsFromLS();\n return storedEvents.filter(function (x) {\n return x.FlightId == flightId;\n });\n }\n\n function upsertEvents(events) {\n var flightIds = events.map(function (x) {\n return x.FlightId;\n });\n var storedEvents = getEventsFromLS();\n var otherEvents = storedEvents.filter(function (x) {\n return !flightIds.includes(x.FlightId);\n });\n var mergeEvents = otherEvents.concat(events);\n setEvents(mergeEvents);\n }\n\n function setEventsForFlightId(flightId, events) {\n var storedEvents = getEventsFromLS();\n var filterEvents = storedEvents.filter(function (x) {\n return x.FlightId != flightId;\n });\n var mergeEvents = filterEvents.concat(events);\n setEvents(mergeEvents);\n }\n\n function setEvents(events) {\n GenericService.saveAll(events, objEvent);\n }\n\n function getEvents(flightId, callback) {\n var uri = encodeURI(apiUrl + '/FlightServiceEvents/GetEvents?flightId=' + flightId);\n return $http.get(uri, {\n 'Content-Type': 'application/json'\n })[\"catch\"](callback);\n }\n\n function saveEvent(event, callback) {\n var eventTimesFixed = _objectSpread({}, event);\n\n if (event.StartTime) {\n eventTimesFixed.StartTime = event.StartTime.clone();\n var startDateObj = new Date(eventTimesFixed.StartTime).fromUTC();\n eventTimesFixed.StartTime = moment(startDateObj);\n } else {\n eventTimesFixed.StartTime = null;\n }\n\n if (event.EndTime) {\n eventTimesFixed.EndTime = event.EndTime.clone();\n var endDateObj = new Date(eventTimesFixed.EndTime).fromUTC();\n eventTimesFixed.EndTime = moment(endDateObj);\n } else {\n eventTimesFixed.EndTime = null;\n }\n\n return $http.post(apiUrl + '/FlightServiceEvents/SaveEvent', eventTimesFixed, {\n 'Content-Type': 'application/json'\n })[\"catch\"](callback);\n }\n\n function cleanOldDataServiceEvents(responseFlightIds) {\n var storedEvents = getEventsFromLS();\n var previousEvents = storedEvents.filter(function (x) {\n return responseFlightIds.includes(x.FlightId);\n });\n setEvents(previousEvents);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('GroomingCategoriesFactory', GroomingCategoriesFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name GroomingCategoriesFactory\r\n * @description \r\n * Get grooming categories\r\n * @ngInject\r\n */\n\n function GroomingCategoriesFactory($http, apiUrl, GenericService) {\n var groomingReportsByCrew = {};\n var service = {\n setGroomingCategories: setGroomingCategories,\n getGroomingCategories: getGroomingCategories,\n collectGroomingReports: collectGroomingReports,\n saveGroomingReports: saveGroomingReports,\n loadGroomingReports: loadGroomingReports,\n clearGroomingReportsFromStorage: clearGroomingReportsFromStorage\n };\n /**\r\n * Initialize the GroomingCategory\r\n * @memberof GroomingCategoriesFactory\r\n */\n\n function GroomingCategory() {\n this.Id = null;\n this.Label = null;\n this.Description = null;\n this.OrderNo = null;\n this.Active = false;\n }\n\n var objEventType = 'groomingCategories';\n var objCallback = GroomingCategory;\n /**\r\n * Save grooming categories\r\n * @memberof GroomingCategoriesFactory\r\n * @param {Array} GroomingCategories\r\n */\n\n function setGroomingCategories(groomingCategories) {\n GenericService.saveAll(groomingCategories, objEventType);\n }\n /**\r\n * Get Event Types\r\n * @memberof FlightServiceEventsFactory\r\n * @returns {Array} EventTypes \r\n */\n\n\n function getGroomingCategories() {\n return GenericService.list(objEventType, objCallback);\n }\n\n function collectGroomingReports(groomingReportsByCrew) {\n var groomingReports = [];\n\n if (groomingReportsByCrew) {\n for (var crewId in groomingReportsByCrew) {\n var crewReports = groomingReportsByCrew[crewId];\n crewReports.forEach(function (category) {\n if (category.UserInput && category.UserInput.trim() !== \"\") {\n groomingReports.push({\n crewId: crewId,\n groomingCategoryId: category.Id,\n feedback: category.UserInput.trim()\n });\n }\n });\n }\n }\n\n return groomingReports;\n }\n\n function saveGroomingReports(groomingReports) {\n localStorage.setItem('groomingReports', JSON.stringify(groomingReports));\n }\n\n ;\n\n function loadGroomingReports() {\n return JSON.parse(localStorage.getItem('groomingReports')) || {};\n }\n\n ;\n\n function clearGroomingReportsFromStorage() {\n localStorage.removeItem('groomingReports');\n }\n\n ;\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('GroomimgCategoriesModalCtrl', GroomimgCategoriesModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name GroomimgCategoriesModalCtrl\r\n * @description \r\n * Grooming Categories Form Modal\r\n * @ngInject\r\n */\n\n function GroomimgCategoriesModalCtrl($scope, $uibModalInstance, crewData, groomingCategories) {\n $scope.crewData = crewData;\n var originalCategories = angular.copy(groomingCategories); // Deep copy for preservation\n\n $scope.groomingCategories = angular.copy(groomingCategories); // Working copy for the modal\n\n $scope.close = close;\n $scope.save = save;\n\n $scope.isSaveEnabled = function () {\n return $scope.groomingCategories.every(function (category) {\n if (category.isSelected) {\n return category.UserInput && category.UserInput.trim() !== '';\n }\n\n return true;\n });\n };\n\n $scope.toggleCategorySelection = function (category) {\n category.isSelected = !category.isSelected; // Clear remarks if the category is unchecked\n\n if (!category.isSelected) {\n category.UserInput = \"\"; // Reset the input field\n }\n }; // Function to clear specific input\n\n\n $scope.clearInput = function (category) {\n category.UserInput = '';\n }; // Close the modal\n\n\n function close() {\n $scope.groomingCategories = angular.copy(originalCategories);\n $uibModalInstance.dismiss('cancel');\n }\n\n function save() {\n angular.copy($scope.groomingCategories, groomingCategories); // Close the modal and return the updated grooming categories\n\n $uibModalInstance.close($scope.groomingCategories);\n }\n\n ;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('gdCrewInfo', gdCrewInfo);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name crewInfo\r\n * @restrict E\r\n * @description\r\n * Crew Table with a double row per crew member\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function gdCrewInfo($uibModal, UserFactory) {\n function link(scope) {\n scope.user = UserFactory.getUser();\n scope.openPhoneConfirmation = openPhoneConfirmation;\n scope.showInfoRow = showInfoRow;\n\n function openPhoneConfirmation(_crew) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/CrewInfo/dlgConfirmCrewCall.html',\n controller: 'CrewCallCtrl',\n size: 'md',\n resolve: {\n crew: function crew() {\n return _crew;\n },\n groundDutyId: function groundDutyId() {\n return scope.grounddutyid;\n },\n flightId: function flightId() {\n return null;\n }\n }\n });\n modalInstance.result.then(function (confirm) {});\n }\n\n function showInfoRow(item) {\n var differentUser = scope.user.aimsId != item.AIMS_ID;\n var phoneAvailable = item.PhoneNumber && item.PhoneNumber != '';\n return differentUser && phoneAvailable;\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/GroundDuty/gdCrewInfo.tpl.html',\n scope: {\n crew: \"=\",\n grounddutyid: \"=\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('GroundDutyCtrl', GroundDutyCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name GroundDutyCtrl\r\n * @description \r\n * Shows the ground duty information\r\n * @ngInject\r\n */\n\n function GroundDutyCtrl(GroundDutyFactory, CourseFactory, TrainingSessionFactory, $scope, $location, $routeParams) {\n $scope.toggleCrewList = toggleCrewList;\n $scope.toggleEditMode = toggleEditMode;\n $scope.selectTrainee = selectTrainee;\n $scope.refresh = refresh;\n $scope.refreshSuccess = true;\n $scope.isRefreshing = false;\n $scope.instructors = [];\n $scope.trainees = [];\n var groundDutyId = Number($routeParams.groundDutyId);\n var groundDuty = GroundDutyFactory.getGroundDutyFromStorage(groundDutyId);\n $scope.dutyCourses = GroundDutyFactory.getGroundDutyActiveCourses(groundDutyId);\n $scope.groundDutyId = groundDutyId;\n\n if (!groundDuty) {\n // go to dashboard if no groundDuty\n $location.path(\"/\");\n } else {\n //Toggle trainees\n groundDuty.Trainees.forEach(function (relatedTrainees) {\n relatedTrainees.isCollapsed = false;\n relatedTrainees.dynamicSize = 10;\n }); //Collect all trainees in list\n\n var traineesFlat = [];\n groundDuty.Trainees.forEach(function (related) {\n related.CrewMembers.forEach(function (trainee) {\n traineesFlat.push(trainee);\n });\n });\n groundDuty.traineesFlat = traineesFlat;\n\n if (groundDuty.RelatedGroundDuties) {\n $scope.courses = GroundDutyFactory.getGroundDutyActiveCourses(groundDutyId);\n }\n\n updateCrewMemberScopes(groundDuty);\n $scope.groundDuty = groundDuty;\n $scope.groundDutyId = groundDutyId;\n }\n\n function toggleCrewList(relatedTrainees) {\n relatedTrainees.isCollapsed = !relatedTrainees.isCollapsed;\n if (relatedTrainees.isCollapsed) relatedTrainees.dynamicSize = relatedTrainees.CrewMembers.length;else relatedTrainees.dynamicSize = 10;\n }\n\n function toggleEditMode(elem, className) {\n $('body').find('div#' + elem + ' > div').not('.tip').hide(\"slow\");\n $('body').find('div#' + elem + ' div.' + className).not('.tip').show(\"slow\");\n }\n /**\r\n * Edit ground duty's attendance list\r\n * @param {object} trainee \r\n */\n\n\n function selectTrainee(trainee) {\n //Value will be saved in ground duty's crew members\n trainee.Absent = !trainee.Absent;\n GroundDutyFactory.updateGroundDuty($scope.groundDuty);\n }\n /**\r\n * Sync ground duty\r\n */\n\n\n function refresh() {\n var courseIds = $scope.dutyCourses.map(function (x) {\n return x.CourseId;\n }).filter(onlyUnique);\n var refreshGroundDuty = {\n DutyId: groundDutyId,\n CourseIds: courseIds\n };\n $scope.isRefreshing = true; //get latest info\n\n GroundDutyFactory.refresh(refreshGroundDuty, function (responseData) {\n $scope.isRefreshing = false;\n $scope.refreshSuccess = true; //update ground duty.\n\n var groundDuty = responseData.data.GroundDuty;\n\n if (groundDuty && groundDuty.Id != 0 && groundDuty.Code) {\n GroundDutyFactory.mergeGroundDutyInfo(groundDuty);\n } //Save training\n\n\n var trainingCourses = responseData.data.TrainingCourses;\n\n if (trainingCourses && trainingCourses.length) {\n trainingCourses.forEach(function (trainingCourse) {\n CourseFactory.upsertCourse(trainingCourse, function (course) {\n TrainingSessionFactory.applyTraineeInfoToSession(course, course.Id, $scope.groundDuty.DutyDateS, groundDutyId, function (session) {});\n });\n });\n }\n\n updateCrewMemberScopes(groundDuty);\n })[\"catch\"](function () {\n $scope.refreshSuccess = false;\n $scope.isRefreshing = false;\n });\n }\n\n function updateCrewMemberScopes(groundDuty) {\n if (groundDuty && groundDuty.RelatedGroundDuties && groundDuty.RelatedGroundDuties.length > 0) {\n var relatedDutyIns = groundDuty.RelatedGroundDuties.filter(function (x) {\n return x.IsInstructor == true;\n });\n\n if (relatedDutyIns && relatedDutyIns.length > 0) {\n $scope.instructors = relatedDutyIns[0].CrewMembers;\n }\n\n var relatedDutyTr = groundDuty.RelatedGroundDuties.filter(function (x) {\n return x.IsInstructor == false;\n });\n\n if (relatedDutyTr && relatedDutyTr.length > 0) {\n $scope.trainees = relatedDutyTr.flatMap(function (a) {\n return a.CrewMembers;\n });\n }\n }\n }\n\n function onlyUnique(value, index, self) {\n return self.indexOf(value) === index;\n }\n }\n})();\n\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('GroundDutyFactory', GroundDutyFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name GroundDutyFactory\r\n * @description \r\n * Add, Update and Get Ground Duties.\r\n * @ngInject\r\n */\n\n function GroundDutyFactory(GenericService, $http, apiUrl) {\n /**\r\n * Initialize the GroundDuty\r\n * @memberof GroundDutyFactory\r\n */\n function GroundDuty() {\n this.Id = null;\n this.Duty = null;\n this.DutyDescription = null;\n this.DutyBegin = null;\n this.DutyEnd = null;\n this.GetId = GetId;\n this.isTraining = false;\n this.icon = null;\n this.Instructors = new Array();\n this.Trainees = new Array();\n this.isManualEntry = false;\n this.hasPendingCourse = false;\n }\n\n var objType = 'groundDuty';\n var objCallback = GroundDuty;\n var service = {\n getGroundDutiesFromStorage: getGroundDutiesFromStorage,\n setGroundDutiesToStorage: setGroundDutiesToStorage,\n getGroundDutyFromStorage: getGroundDutyFromStorage,\n getGroundDutyActiveCourses: getGroundDutyActiveCourses,\n getGroundDutiesByDutyNo: getGroundDutiesByDutyNo,\n mergeGroundDutyInfo: mergeGroundDutyInfo,\n updateGroundDuty: updateGroundDuty,\n setCourseCompleted: setCourseCompleted,\n setCoursePending: setCoursePending,\n isLastDay: isLastDay,\n mergeGroundDutiesToStorage: mergeGroundDutiesToStorage,\n refresh: refresh,\n addGroundDuty: addGroundDuty,\n removeGroundDuty: removeGroundDuty,\n getManualGroundDutiesFromStorage: getManualGroundDutiesFromStorage,\n getFirstAndLastDateOfGroundDuties: getFirstAndLastDateOfGroundDuties\n };\n /**\r\n * Overide default get Id\r\n * @memberof GroundDutyFactory\r\n * @returns {number} Id \r\n */\n\n function GetId() {\n return this.Id;\n }\n /**\r\n * Get Ground Duties.\r\n * @memberof GroundDutyFactory\r\n * @returns {Array} GroundDuties \r\n */\n\n\n function getGroundDutiesFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Get GroundDuty from storage groundDuties\r\n * @memberof GroundDutyFactory\r\n * @param {number} groundDutyId \r\n * @return {object} groundDuty\r\n */\n\n\n function getGroundDutyFromStorage(groundDutyId) {\n var groundDuty = GenericService.get(groundDutyId, objType, objCallback);\n var instructors = [];\n var trainees = [];\n\n if (groundDuty != null && groundDuty != undefined) {\n //only training\n if (groundDuty.RelatedGroundDuties && groundDuty.RelatedGroundDuties.length > 1) {\n groundDuty.isTraining = true;\n groundDuty.RelatedGroundDuties.forEach(function (element) {\n if (element.IsInstructor) {\n instructors.push(element);\n } else {\n trainees.push(element);\n }\n });\n groundDuty.Trainees = trainees;\n groundDuty.Instructors = instructors;\n }\n }\n\n return groundDuty;\n }\n /**\r\n * Save Ground Duties to storage\r\n * @memberof GroundDutyFactory\r\n * @param {Array} GroundDuties A list of Ground Duties\r\n */\n\n\n function setGroundDutiesToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**Save Ground Duties to storage but keep local storage values\r\n * Necessary to maintain Absent values in training duties\r\n */\n\n\n function mergeGroundDutiesToStorage(objList, fromSync) {\n var groundDuties = getGroundDutiesFromStorage();\n\n if (!fromSync) {\n groundDuties.filter(function (x) {\n return x.isManualEntry;\n }).forEach(function (duty) {\n objList.push(duty);\n });\n }\n\n if (groundDuties) {\n objList.forEach(function (incomingDuty) {\n if (incomingDuty.RelatedGroundDuties) {\n var incomingTraineesFlat = [];\n incomingDuty.RelatedGroundDuties.filter(function (x) {\n return !x.IsInstructor;\n }).forEach(function (related) {\n related.CrewMembers.forEach(function (trainee) {\n incomingTraineesFlat.push(trainee);\n });\n }); //Initialize all as present\n\n incomingTraineesFlat.forEach(function (incomingTrainee) {\n incomingTrainee.Absent = false;\n }); //Copy Absent value from existing local storage duties\n\n var existingDuty = groundDuties.find(function (x) {\n return x.Id == incomingDuty.Id;\n });\n\n if (existingDuty && existingDuty.RelatedGroundDuties) {\n var existingTraineesFlat = [];\n existingDuty.RelatedGroundDuties.filter(function (x) {\n return !x.IsInstructor;\n }).forEach(function (related) {\n related.CrewMembers.forEach(function (trainee) {\n existingTraineesFlat.push(trainee);\n });\n });\n incomingTraineesFlat.forEach(function (incomingTrainee) {\n var existingTrainee = existingTraineesFlat.find(function (x) {\n return x.Id == incomingTrainee.Id;\n });\n\n if (existingTrainee) {\n incomingTrainee.Absent = existingTrainee.Absent;\n }\n });\n }\n }\n });\n }\n\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Get GroundDuties of a Crew Route\r\n * @memberof GroundDutyFactory \r\n * @param {number} dutyNo \r\n * @param {string} dutyDay\r\n * @return {array} groundDuties\r\n */\n\n\n function getGroundDutiesByDutyNo(dutyNo, dutyDay) {\n var groundDuties = getGroundDutiesFromStorage();\n if (groundDuties == null) return [];\n var result = [];\n var instructors = [];\n var trainees = [];\n var arrayLength = groundDuties.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (groundDuties[i].DutyNo == dutyNo && groundDuties[i].DutyDay == dutyDay) {\n //only training\n if (groundDuties[i].RelatedGroundDuties && groundDuties[i].RelatedGroundDuties.length > 1) {\n groundDuties[i].isTraining = true;\n instructors = [];\n trainees = [];\n groundDuties[i].RelatedGroundDuties.forEach(function (element) {\n if (element.IsInstructor) {\n instructors.push(element);\n } else {\n trainees.push(element);\n }\n });\n groundDuties[i].Trainees = trainees;\n groundDuties[i].Instructors = instructors;\n }\n\n result.push(groundDuties[i]);\n }\n }\n\n return result;\n }\n /**\r\n * Merge new info to current Ground Duty\r\n * @memberof GroundDutyFactory\r\n * @param {object} duty \r\n */\n\n\n function mergeGroundDutyInfo(duty) {\n var currentGroundDutyInfo = GenericService.get(duty.Id, objType, objCallback);\n currentGroundDutyInfo.Code = duty.Code;\n currentGroundDutyInfo.Description = duty.Description;\n currentGroundDutyInfo.DutyDate = duty.DutyDate;\n currentGroundDutyInfo.GroundDutyNo = duty.GroundDutyNo;\n currentGroundDutyInfo.DutyDateS = duty.DutyDateS;\n currentGroundDutyInfo.DutyBegin = duty.DutyBegin;\n currentGroundDutyInfo.DutyEnd = duty.DutyEnd;\n currentGroundDutyInfo.DutyDay = duty.DutyDay;\n currentGroundDutyInfo.DutyNo = duty.DutyNo;\n currentGroundDutyInfo.Route = duty.Route;\n\n if (currentGroundDutyInfo.RelatedGroundDuties && currentGroundDutyInfo.RelatedGroundDuties.length) {\n currentGroundDutyInfo.RelatedGroundDuties = duty.RelatedGroundDuties;\n }\n\n GenericService.save(currentGroundDutyInfo, objType, objCallback);\n }\n /**\r\n * Check in calendar if this is the last day of this duty\r\n * @param {object} groundDuty \r\n */\n\n\n function isLastDay(groundDuty, course) {\n //Get duty's Trainee codes\n var traineeCodes = _toConsumableArray(new Set(groundDuty.RelatedGroundDuties.filter(function (x) {\n return x.Courses && x.Courses.find(function (y) {\n return y.CourseId == course.Id;\n });\n }).map(function (r) {\n return r.Code;\n }))); //Get Remaining Trainee codes\n\n\n var remainingTraineeCodes = [];\n var remainingGroundDuties = GenericService.list(objType, objCallback) //get all grounDuties\n .filter(function (x) {\n return x.RelatedGroundDuties && x.RelatedGroundDuties.length > 1 && //filter only training\n dateDifference(groundDuty.DutyBegin, x.DutyBegin) < 0;\n }); //check later duty date\n\n remainingGroundDuties.forEach(function (groundDuty) {\n var codes = groundDuty.RelatedGroundDuties.filter(function (x) {\n return !x.IsInstructor;\n }).map(function (y) {\n return y.Code;\n }); //only trainee codes\n\n remainingTraineeCodes = remainingTraineeCodes.concat(codes);\n });\n remainingTraineeCodes = _toConsumableArray(new Set(remainingTraineeCodes)); //remove duplicates\n\n return !remainingTraineeCodes.some(function (r) {\n return traineeCodes.includes(r);\n });\n }\n /**\r\n * Compares two dates\r\n * @param {date} currentDate \r\n * @param {date} checkDate \r\n */\n\n\n function dateDifference(currentDate, checkDate) {\n var currentDate = moment(currentDate);\n var checkDate = moment(checkDate);\n return currentDate.diff(checkDate);\n }\n\n function updateGroundDuty(groundDuty) {\n GenericService.save(groundDuty, objType, objCallback);\n }\n\n function addGroundDuty(groundDuty) {\n var storedGroundDuty = GenericService.get(groundDuty.Id, objType, objCallback);\n\n if (!storedGroundDuty) {\n GenericService.add(groundDuty, objType, objCallback);\n } else {\n updateGroundDuty(groundDuty);\n }\n }\n\n function removeGroundDuty(groundDuty) {\n GenericService.remove(groundDuty, objType, objCallback);\n }\n\n function setCourseCompleted(dutyId, courseId) {\n var groundDuty = GenericService.get(dutyId, objType, objCallback);\n groundDuty.RelatedGroundDuties.filter(function (x) {\n return x.Courses;\n }).forEach(function (item) {\n var groundDutyCourse = item.Courses.find(function (x) {\n return x.CourseId == courseId;\n });\n\n if (groundDutyCourse) {\n groundDutyCourse.Status = \"Completed\";\n }\n });\n var allCoursesAreCompleted = false;\n\n if (groundDuty.RelatedGroundDuties && groundDuty.RelatedGroundDuties.length > 0) {\n allCoursesAreCompleted = groundDuty.RelatedGroundDuties.filter(function (x) {\n return x.Courses && x.Courses.length > 0;\n }).every(function (relatedDuty) {\n return relatedDuty.Courses.every(function (course) {\n return course.Status == \"Completed\";\n });\n });\n }\n\n if (groundDuty.isManualEntry && allCoursesAreCompleted) {\n groundDuty.hasPendingCourse = false;\n }\n\n updateGroundDuty(groundDuty);\n }\n\n function setCoursePending(dutyId, courseId) {\n var groundDuty = GenericService.get(dutyId, objType, objCallback);\n groundDuty.RelatedGroundDuties.filter(function (x) {\n return x.Courses;\n }).forEach(function (item) {\n var groundDutyCourse = item.Courses.find(function (x) {\n return x.CourseId == courseId;\n });\n if (groundDutyCourse) groundDutyCourse.Status = \"Pending\";\n });\n updateGroundDuty(groundDuty);\n }\n\n function getGroundDutyActiveCourses(groundDutyId) {\n var groundDuty = GenericService.get(groundDutyId, objType, objCallback);\n var courses = [];\n\n if (groundDuty != null && groundDuty != undefined) {\n if (groundDuty.RelatedGroundDuties && groundDuty.RelatedGroundDuties.length > 1) {\n groundDuty.RelatedGroundDuties.filter(function (x) {\n return !x.IsInstructor && x.Courses;\n }).forEach(function (item) {\n courses.push.apply(courses, _toConsumableArray(item.Courses));\n });\n }\n }\n\n return courses;\n }\n\n function refresh(refreshGroundDuty, callback) {\n return $http.post(apiUrl + '/GroundDuty/Refresh', refreshGroundDuty, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n /**Get manual Ground Duties from storage*/\n\n\n function getManualGroundDutiesFromStorage() {\n var groundDuties = getGroundDutiesFromStorage();\n return groundDuties.filter(function (x) {\n return x.isManualEntry;\n });\n }\n\n function getFirstAndLastDateOfGroundDuties() {\n var groundDuties = getGroundDutiesFromStorage();\n\n var parseDate = function parseDate(dateString) {\n return new Date(dateString);\n };\n\n var firstDutyDate = null;\n var lastDutyDate = null;\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = groundDuties[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var obj = _step.value;\n var currentDate = parseDate(obj.DutyDate);\n\n if (!firstDutyDate || currentDate < firstDutyDate) {\n firstDutyDate = currentDate;\n }\n\n if (!lastDutyDate || currentDate > lastDutyDate) {\n lastDutyDate = currentDate;\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator[\"return\"] != null) {\n _iterator[\"return\"]();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return {\n firstDate: firstDutyDate,\n lastDate: lastDutyDate\n };\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('SearchPastGDCtrl', SearchPastGDCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SearchPastGDCtrl\r\n * @description \r\n * Search pending duties \r\n * @ngInject\r\n */\n\n function SearchPastGDCtrl($scope, GroundDutyFactory, PastDutyFactory, $uibModalInstance, $route, CourseFactory, defaultCalendarDate, CrewRouteFactory, FlightFactory) {\n $scope.dutyId = null;\n $scope.showContent = 'search';\n $scope.course = {\n isCourseLimited: true\n };\n $scope.hasError = false; // cancel\n\n $scope.doCancel = doCancel;\n $scope.closeModal = closeModal;\n $scope.showMessage = true;\n var today = new Date().toUTC();\n\n if (defaultCalendarDate) {\n today = new Date(defaultCalendarDate).toUTC();\n }\n\n $scope.dutyDatePicker = {\n value: today,\n format: 'dd-MM-yyyy',\n opened: false\n };\n $scope.dateFormat = 'dd-MM-yyyy';\n $scope.openDatepicker = openDatepicker;\n\n function openDatepicker() {\n $scope.dutyDatePicker.opened = true;\n }\n\n $scope.searchGDByDate = searchGDByDate;\n $scope.searchNotStarted = searchNotStarted;\n\n function searchGDByDate() {\n $scope.hasError = false;\n $scope.showContent = 'loading';\n PastDutyFactory.getPastDuties($scope.dutyDatePicker.value.toString('yyyy-MM-dd')).then(function (res) {\n return handleSubmitResponse(res);\n })[\"catch\"](function (res) {\n return handleFailedResponse(res);\n });\n }\n\n function searchNotStarted() {\n $scope.hasError = false;\n $scope.showContent = 'loading';\n PastDutyFactory.getNotStartedDuties($scope.dutyDatePicker.value.toString('yyyy-MM-dd')).then(function (res) {\n return handleNotStartedSubmitResponse(res);\n })[\"catch\"](function (res) {\n return handleNotStartedFailedResponse(res);\n });\n } // search pending gd\n\n\n $scope.searchGD = searchGD;\n /**\r\n * Close the modal\r\n * @memberof SearchPastGDCtrl\r\n */\n\n function doCancel() {\n $uibModalInstance.close('cancel');\n }\n\n function searchGD() {\n $scope.showContent = 'loading';\n PastDutyFactory.getPastDuties('').then(function (res) {\n return handleSubmitResponse(res);\n })[\"catch\"](function (res) {\n return handleFailedResponse(res);\n });\n }\n\n function handleSubmitResponse(res) {\n $scope.showContent = 'results';\n $scope.availableCources = res.data.trainingCourses;\n $scope.pendingDuties = res.data.pendingGroundDuties;\n $scope.flightTrainings = res.data.pendingRoutes;\n $scope.pendingFlightCourses = res.data.flightCourses;\n var flights = res.data.flightsForPendingRoutes;\n FlightFactory.insertFlightsWithPendingTrainings(flights);\n $scope.availableCources.forEach(function (course) {\n course.HasLimitedInfo = true;\n CourseFactory.upsertCourse(course, function () {});\n });\n $scope.pendingDuties.forEach(function (duty) {\n duty.isManualEntry = true;\n duty.hasPendingCourse = true;\n GroundDutyFactory.addGroundDuty(duty);\n });\n $scope.flightTrainings.forEach(function (pendingRoute) {\n pendingRoute.isManualEntry = true;\n pendingRoute.hasPendingCourse = true;\n CrewRouteFactory.addCrewRouteDuty(pendingRoute);\n });\n $scope.pendingFlightCourses.forEach(function (course) {\n course.HasLimitedInfo = true;\n CourseFactory.upsertCourse(course, function () {});\n });\n }\n\n function handleNotStartedSubmitResponse(res) {\n $scope.showContent = 'notStartedResults';\n $scope.notStartedGroundDuties = res.data.notStartedGroundDuties;\n $scope.groundCourses = res.data.trainingCourses;\n $scope.notStartedGroundDuties.forEach(function (duty) {\n duty.isManualEntry = true;\n duty.hasPendingCourse = true;\n GroundDutyFactory.addGroundDuty(duty);\n });\n $scope.groundCourses.forEach(function (course) {\n course.HasLimitedInfo = true;\n CourseFactory.upsertCourse(course, function () {});\n });\n }\n\n function closeModal() {\n $uibModalInstance.close();\n $route.reload();\n }\n\n function handleFailedResponse(res) {\n $scope.showContent = 'results';\n $scope.hasError = true;\n }\n\n function handleNotStartedFailedResponse(res) {\n $scope.showContent = 'notStartedResults';\n $scope.hasError = true;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('PastDutyFactory', PastDutyFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PastDutyFactory\r\n * @description \r\n * Get Past Duties.\r\n * @ngInject\r\n */\n\n function PastDutyFactory($http, apiUrl) {\n var service = {\n getPastDuties: getPastDuties,\n getNotStartedDuties: getNotStartedDuties\n };\n\n function getPastDuties(selectedDate, callback) {\n return $http.get(apiUrl + '/Training/GetPastDuties?specificDutyDate=' + selectedDate, {\n 'Content-Type': 'application/json'\n })[\"catch\"](callback);\n }\n\n function getNotStartedDuties(selectedDate, callback) {\n return $http.get(apiUrl + '/Training/GetNotStartedDuties?specificDutyDate=' + selectedDate, {\n 'Content-Type': 'application/json'\n })[\"catch\"](callback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.config(compileProviderConfig);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc config\r\n * @name compileProviderConfig\r\n * @description \r\n * Config aHref Sanitization Whitelist (make \"safe\" to download image from data url)\r\n * @ngInject\r\n */\n\n function compileProviderConfig($compileProvider) {\n $compileProvider.aHrefSanitizationWhitelist(/^\\s*(https?|ftp|mailto|file|ghttps?|ms-appx|x-wmapp0|data|tel):/);\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict'; // By default, AngularJS will catch errors and log them to\n // the Console. We want to keep that behavior; however, we\n // want to intercept it so that we can also log the errors\n // to the server for later analysis.\n\n a3_cabin_reports.config(exceptionConfig);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc config\r\n * @name exceptionConfig\r\n * @description \r\n * By default, AngularJS will catch errors and log them to\r\n * the Console. We want to keep that behavior; however, we\r\n * want to intercept it so that we can also log the errors\r\n * to the server for later analysis.\r\n * @ngInject\r\n */\n\n function exceptionConfig($provide) {\n $provide.decorator('$exceptionHandler', extendExceptionHandler);\n }\n /**\r\n * @memberof exceptionConfig\r\n * @description \r\n * Override default exception handling and log errors \r\n * @ngInject\r\n */\n\n\n function extendExceptionHandler($delegate, LogService) {\n return function (exception, cause) {\n $delegate(exception, cause);\n /**\r\n * Could add the error to a service's collection,\r\n * add errors to $rootScope, log errors to remote web server,\r\n * or log locally. Or throw hard. It is entirely up to you.\r\n * throw exception;\r\n */\n\n LogService.error(exception, cause);\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('http401interceptor', http401interceptor);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name http401interceptor\r\n * @description \r\n * Redirect HTTP401 to login page, examine json format on success\r\n * @ngInject\r\n */\n\n function http401interceptor($q, $location, $log, LogService) {\n return {\n 'response': function response(_response) {\n // do something on success\n //expecting specific object as a response: success:true/false,errorMessage:string,data:any not null object\n //var contentType=response.headers(\"content-type\");\n var header = \"\";\n if (typeof _response != 'undefined' && _response != null && _response && typeof _response.headers != 'undefined' && _response.headers != null && _response.headers && _response.headers() && _response.headers(\"content-type\")) header = _response.headers(\"content-type\").substring(0, 16);\n\n if (header === \"application/json\") {\n var errorMessage = \"\";\n var isError = false;\n\n if (_response == null || _response.data == null || _response.data.success == null || _response.data.errorMessage == null || _response.data.data === 'undefined') {\n isError = true;\n errorMessage = \"Server response not found\";\n } else if (_response.data.success == false) {\n isError = true;\n errorMessage = _response.data.errorMessage;\n }\n\n if (isError) $q.reject(_response, errorMessage);\n } else {\n //try to log error cases\n var err = null;\n if (typeof _response === 'undefined' || _response == null) err = \"Response was empty\";else if (!_response.headers) err = \"Response does not contain headers\";else if (!_response.status) err = \"Response does not have a status\";else if (_response.status >= 400) err = \"Response status was \" + _response.status + \" instead of 200\";\n if (err != null) LogService.debug(err);\n }\n\n return _response || $q.when(_response);\n },\n // optional method\n 'responseError': function responseError(rejection) {\n if (rejection.status === 401) {\n $log.error('Authorization failed. Need to login again');\n\n if ($location.path() != '/login') {\n $location.path('/login'); //force refresh so that the browser will download any updates from the cache.manifest\n //without refresh, user may stick to an older version for ever\n\n setTimeout(function () {\n window.location.reload(true);\n }, 1000);\n }\n\n return $q.reject(rejection);\n } else {\n return $q.reject(rejection);\n }\n }\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('httpCrewTokenInterceptor', httpCrewTokenInterceptor);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name httpCrewTokenInterceptor\r\n * @description \r\n * Add CrewToken on non login requests\r\n * @ngInject\r\n */\n\n function httpCrewTokenInterceptor($location, localStorageMD5Service, UserTokenFactory) {\n return {\n request: function request(config) {\n if ($location.$$url != \"/login\") {\n // get the user token\n var user = localStorageMD5Service.get('user');\n var token = '';\n if (user != null) token = user.token;\n config.headers['X-CrewToken'] = token;\n }\n\n return config;\n },\n response: function response(_response) {\n if (_response.headers()['content-type'] === \"application/json; charset=utf-8\") {\n var expiresAt = _response.headers()['x-expires-token'];\n\n var crewToken = _response.headers()['x-rolling-token'];\n\n if (expiresAt && crewToken) {\n var user = localStorageMD5Service.get('user');\n\n if (user != null) {\n user.token = crewToken;\n user.expires = expiresAt;\n localStorageMD5Service.set('user', user);\n }\n\n UserTokenFactory.setToken(crewToken);\n }\n }\n\n return _response;\n }\n };\n }\n})();\n\"use strict\";\n\nfunction _typeof(obj) { if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('httpHeaderInterceptor', httpHeaderInterceptor);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name httpHeaderInterceptor\r\n * @description \r\n * Add CrewToken on non login requests\r\n * @ngInject\r\n */\n\n function httpHeaderInterceptor($location, localStorageMD5Service) {\n return {\n request: function request(config) {\n if ($location.$$url != \"/login\") {\n if (config.url.includes(\"api\")) {\n var user = localStorageMD5Service.get('user');\n var aimsIdToString = user.aimsId.toString();\n\n if (config.method === \"POST\" || config.method === \"PUT\") {\n var dataToHash = _typeof(config.data) === \"object\" ? angular.toJson(config.data) + aimsIdToString : config.data + aimsIdToString;\n var hash = dataToHash.getHash();\n config.headers['X-VCode'] = hash;\n } else if (config.method === \"GET\") {\n var absolutePath = config.url;\n var stringToHash = absolutePath.substring(absolutePath.lastIndexOf(\"/\") + 1, absolutePath.length);\n var hash = (stringToHash + aimsIdToString).getHash();\n config.headers['X-VCode'] = hash;\n }\n }\n }\n\n return config;\n }\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.config(httpProviderConfig);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc config\r\n * @name httpProviderConfig\r\n * @description \r\n * Register interceptors and modify headers\r\n * @ngInject\r\n */\n\n function httpProviderConfig($httpProvider) {\n $httpProvider.defaults.useXDomain = true;\n delete $httpProvider.defaults.headers.common['X-Requested-With'];\n $httpProvider.interceptors.push('http401interceptor');\n $httpProvider.interceptors.push('httpCrewTokenInterceptor');\n $httpProvider.interceptors.push('httpHeaderInterceptor');\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.config(localStorageMD5Config);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc config\r\n * @name localStorageMD5Config\r\n * @description \r\n * Config localStorageMD5ServiceProvider directly by using localStorageMD5ServiceProvider\r\n * @ngInject\r\n */\n\n function localStorageMD5Config(localStorageMD5ServiceProvider, localStorageServiceProvider) {\n //localStorageMD5ServiceProvider.help();\n var regx = /[?&]secure[&#]?/;\n\n if (regx.exec(window.location.href)) {\n console.log('*** SECURE MODE ***');\n localStorageServiceProvider.setStorageType('sessionStorage');\n }\n\n localStorageServiceProvider.setPrefix('a3.cabin.reports');\n localStorageServiceProvider.setStorageCookie(10, '/');\n localStorageMD5ServiceProvider.enableCompression();\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory(\"LogService\", LogService);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name LogService\r\n * @description \r\n * The error log service is our wrapper around the core error\r\n * handling ability of AngularJS. Notice that we pass off to\r\n * the native \"$log\" method and then handle our additional\r\n * server-side logging.\r\n * @ngInject\r\n */\n\n function LogService($log, $injector, $window, apiUrl, version, UserTokenFactory) {\n var lastError = null; //define how many seconds to wait before resending the same error (to avoid multiple errors for the same prob)\n\n var acceptedTimeDiff = 5;\n\n function post(errorMessage, stackTrace, cause) {\n try {\n var $http = $injector.get(\"$http\");\n /*// get the user token\r\n var user = UserFactory.getUser();\r\n var token = '';\r\n if (user != null)\r\n \ttoken = user.token;*/\n\n var token = UserTokenFactory.getToken(); // Log the JavaScript error to the server.\n // --\n // NOTE: In this demo, the POST URL doesn't\n // exists and will simply return a 404.\n\n $http({\n method: \"POST\",\n url: apiUrl + \"/log\",\n contentType: \"application/json\",\n data: {\n errorUrl: $window.location.href,\n errorMessage: version + \" \" + errorMessage,\n stackTrace: stackTrace,\n cause: cause || \"\"\n },\n beforeSend: function beforeSend(request) {\n request.setRequestHeader('X-CrewToken', token);\n }\n });\n } catch (loggingError) {\n // For Developers - log the log-failure.\n $log.warn(\"Error logging failed\");\n $log.log(loggingError);\n }\n }\n\n ;\n\n function postFilter(errorMessage, stackTrace, cause) {\n if (lastError != null && lastError.errorDescr == errorMessage) {\n var timestampDiff = Date.now() - lastError.timestamp;\n var timeDiffInSec = timestampDiff / 1000;\n\n if (timeDiffInSec > acceptedTimeDiff) {\n lastError = {\n 'errorDescr': errorMessage,\n 'timestamp': Date.now()\n };\n post(errorMessage, stackTrace, cause);\n }\n } else {\n lastError = {\n 'errorDescr': errorMessage,\n 'timestamp': Date.now()\n };\n post(errorMessage, stackTrace, cause);\n }\n }\n\n ;\n return {\n debug: function debug(errorMessage, error) {\n if (error == null) {\n error = new Error();\n }\n\n if (errorMessage != null) {\n error.description = errorMessage;\n }\n\n post(error.description, error.stack, \"\");\n },\n error: function error(exception, cause) {\n // Pass off the error to the default error handler\n // on the AngualrJS logger. This will output the\n // error to the console (and let the application\n // keep running normally for the user).\n $log.error.apply($log, arguments); // Now, we need to try and log the error the server.\n // --\n // NOTE: In production, I have some debouncing\n // logic here to prevent the same client from\n // logging the same error over and over again! All\n // that would do is add noise to the log.\n\n var errorMessage = exception.toString(); //var stackTrace = stacktraceService.print({ e: exception });\n //var stackTrace = $log.info({ e: exception });\n\n var stackTrace = exception.stack;\n postFilter(errorMessage, stackTrace, cause);\n }\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('UserTokenFactory', UserTokenFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name UserTokenFactory\r\n * @description \r\n * Used to maintain the user token, outside the localStorage, in order to be accessible from the service which logs js errors\r\n * /(this service may not use localstorage provider)\r\n * @ngInject\r\n */\n\n function UserTokenFactory() {\n return {\n token: '',\n setToken: function setToken(value) {\n this.token = value;\n },\n getToken: function getToken() {\n return this.token;\n }\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('annualLeavesSummary', annualLeavesSummary);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name annualLeavesSummary\r\n * @restrict E\r\n * @description\r\n * Implementation of annual Leaves Summary\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function annualLeavesSummary(AnnualLeavesFactory) {\n function link($scope, element, attrs) {\n $scope.showAnnualLeavesSummary = false;\n var annualLeavesInfo = AnnualLeavesFactory.getAnnualLeavesToStorage();\n\n if (annualLeavesInfo && annualLeavesInfo.length > 0) {\n $scope.showAnnualLeavesSummary = true;\n $scope.annualLeaves = groupAnnualLeavesByType(annualLeavesInfo);\n }\n\n function groupAnnualLeavesByType(annualLeavesInfo) {\n var groupedLeaves = [];\n annualLeavesInfo = annualLeavesInfo.sort(function (a, b) {\n return b.Date < a.Date ? 1 : -1;\n });\n\n for (var i = 0; i < annualLeavesInfo.length; i++) {\n var previousGroup = groupedLeaves[groupedLeaves.length - 1];\n\n if (i != 0 && previousGroup.type == annualLeavesInfo[i].Type && new Date(annualLeavesInfo[i].Date) - new Date(previousGroup.dates[previousGroup.dates.length - 1]) === 86400000) {\n previousGroup.dates.push(annualLeavesInfo[i].Date);\n } else {\n var item = {\n type: annualLeavesInfo[i].Type,\n dates: []\n };\n item.dates.push(annualLeavesInfo[i].Date);\n groupedLeaves.push(item);\n }\n }\n\n return groupedLeaves;\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/LeaveRequest/annual-leaves-summary.tpl.html',\n scope: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('AnnualLeavesFactory', AnnualLeavesFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AnnualLeavesFactory\r\n * @description \r\n * Get Annual Leaves Data \r\n * @ngInject\r\n */\n\n function AnnualLeavesFactory(GenericService, $http, apiUrl) {\n /**\r\n * Initialize the AnnualLeaves\r\n * @memberof CheckInFactory\r\n */\n function AnnualLeaves() {}\n\n var objType = 'AnnualLeaves';\n var objCallback = AnnualLeaves;\n var service = {\n setAnnualLeavesToStorage: setAnnualLeavesToStorage,\n getAnnualLeavesToStorage: getAnnualLeavesToStorage\n };\n /**\r\n * Save Annual Leaves\r\n * @param {array} annualLeavesInInfo \r\n */\n\n function setAnnualLeavesToStorage(annualLeavesInInfo) {\n if (annualLeavesInInfo == undefined || annualLeavesInInfo == null) {\n GenericService.removeAll(objType);\n } else {\n GenericService.saveAll(annualLeavesInInfo, objType, objCallback);\n }\n }\n /**\r\n * Gets annual leaves\r\n * @returns {annualLeavesObj} annualLeavesObj\r\n */\n\n /**\r\n * Get annual leaves\r\n */\n\n\n function getAnnualLeavesToStorage() {\n return GenericService.list(objType, objCallback);\n ;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('flexCombination', FlexCombination);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name FlexCombination\r\n * @restrict E\r\n * @description\r\n * Implementation of Flex Combinations\r\n *\r\n * Initialize the Flex Combination of a season\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function FlexCombination($timeout) {\n function link(scope, element, attrs) {\n angular.forEach(scope.seasonRequest.LeaveRequestPriorityPeriods, function (value, key) {\n var temp = value.MockLeaveRequestPrioritySlots;\n var temp2 = value.LeaveRequestPrioritySlots;\n $timeout(function () {\n value.MockLeaveRequestPrioritySlots = angular.fromJson(temp);\n value.LeaveRequestPrioritySlots = angular.fromJson(temp2);\n });\n });\n scope.sortableOptions = {\n handle: '>.row .myHandle',\n update: function update(e, ui) {},\n stop: function stop(e, ui) {\n for (var i = 0; i < scope.seasonRequest.LeaveRequestPriorityPeriods.length; i++) {\n sortSetupOrderNo(scope.seasonRequest.LeaveRequestPriorityPeriods[i]);\n }\n }\n };\n scope.setupOrderNo = setupOrderNo;\n\n function sortSetupOrderNo(period) {\n if (Array.isArray(period.LeaveRequestPrioritySlots)) {\n for (var i = 0; i < period.LeaveRequestPrioritySlots.length; i++) {\n period.LeaveRequestPrioritySlots[i].OrderNo = i + 1;\n }\n }\n }\n\n ;\n\n function setupOrderNo(period) {\n if (Array.isArray(period.MockLeaveRequestPrioritySlots)) {\n period.LeaveRequestPrioritySlots = [];\n\n for (var i = 0; i < period.MockLeaveRequestPrioritySlots.length; i++) {\n var temp = Object.assign({}, period.MockLeaveRequestPrioritySlots[i]);\n temp.OrderNo = i + 1;\n period.LeaveRequestPrioritySlots.push(temp);\n }\n }\n }\n\n ;\n scope.removeSlot = removeSlot;\n\n function removeSlot(slotIndex, period) {\n period.LeaveRequestPrioritySlotsHelper = [];\n\n for (var i = 0; i < period.LeaveRequestPrioritySlots.length; i++) {\n if (i != slotIndex) {\n period.LeaveRequestPrioritySlotsHelper.push(period.LeaveRequestPrioritySlots[i]);\n }\n }\n\n period.LeaveRequestPrioritySlots = period.LeaveRequestPrioritySlotsHelper;\n period.MockLeaveRequestPrioritySlots = period.LeaveRequestPrioritySlotsHelper;\n setupOrderNo(period);\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/LeaveRequest/flexCombinations.tpl.html',\n scope: {\n seasonConfiguration: '<',\n seasonRequest: '=',\n editable: '<'\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('LeaveRequestCtrl', LeaveRequestCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name LeaveRequestCtrl\r\n * @description \r\n * View Leave Request Tool\r\n * @ngInject\r\n */\n\n function LeaveRequestCtrl($scope, $filter, $route, LeaveRequestFactory, $uibModal, $timeout, $location) {\n $scope.state = 'leaveRequest';\n $scope.getRandomBorderColor = getRandomBorderColor;\n $scope.getRandomTextColor = getRandomTextColor;\n $scope.IsValidLeaveRequest = IsValidLeaveRequest;\n $scope.showHelp = showHelp;\n $scope.showSuccessLeaveApplicationMessage = false;\n $scope.hasErrors = false;\n progressBarBox(true);\n LeaveRequestFactory.getConfigurationDetails(function (responseData) {\n $scope.QualificationGroup = responseData.data.data.QualificationGroup;\n $scope.LeaveRequestInformation = responseData.data.data.LeaveRequestInformation;\n $scope.QualificationGroup.RequestLessDays = $scope.QualificationGroup.RequestLessDays ? $scope.QualificationGroup.RequestLessDays : false;\n $scope.QualificationGroup.RequestNoLeave = $scope.QualificationGroup.RequestNoLeave ? $scope.QualificationGroup.RequestNoLeave : false;\n\n if (responseData.data && responseData.data.data && responseData.data.data.QualificationGroup && responseData.data.data.LeaveRequestInformation) {\n //FOR TEST: \n //$scope.LeaveRequestInformation.GroupStatus=\"PROCESS\";\n $scope.closeDateStr = moment($scope.LeaveRequestInformation.CloseDate).format('Do of MMMM');\n $scope.isOpen = $scope.LeaveRequestInformation.GroupStatus == \"OPEN\";\n $scope.LeaveRequest = {\n YearId: $scope.LeaveRequestInformation.YearId,\n MemberId: $scope.LeaveRequestInformation.MemberId,\n RequestNoleave: responseData.data.data.LeaveRequest ? responseData.data.data.LeaveRequest.RequestNoleave : false,\n // Default: Request Leave selected\n LeaveRequestSeasons: []\n };\n\n if (responseData.data.data.LeaveRequest) {\n $scope.showSuccessLeaveApplicationMessage = true;\n }\n\n if (responseData.data.data.LeaveRequest && !responseData.data.data.LeaveRequest.RequestNoleave) {\n mergeRequest(responseData.data.data.LeaveRequest, $scope.QualificationGroup.Seasons);\n } else {\n initializeNewRequest($scope.QualificationGroup.Seasons); //Temporary: Hide Instructions\n //if($scope.isOpen) $timeout(showHelp,500);\n }\n } else {\n $scope.hasErrors = true;\n }\n\n progressBarBox(false);\n }, function (data) {\n $scope.hasErrors = true;\n progressBarBox(false);\n });\n\n function mergeRequest(leaveRequest, seasons) {\n $scope.LeaveRequest = leaveRequest;\n\n for (var j = 0; j < leaveRequest.LeaveRequestSeasons.length; j++) {\n leaveRequest.LeaveRequestSeasons[j].HasSpecificCombinations = $filter('filter')(leaveRequest.LeaveRequestSeasons[j].LeaveRequestPriorities, {\n Type: 'All'\n }).length > 0;\n\n for (var i = 0; i < seasons.length; i++) {\n if (seasons[i].Id == leaveRequest.LeaveRequestSeasons[j].SeasonId) {\n leaveRequest.LeaveRequestSeasons[j].StartDate = seasons[i].StartDate;\n leaveRequest.LeaveRequestSeasons[j].EndDate = seasons[i].EndDate;\n leaveRequest.LeaveRequestSeasons[j].Slots = seasons[i].Slots;\n leaveRequest.LeaveRequestSeasons[j].Configurations = seasons[i].Configurations;\n setupMockLeaveRequestPriorities(leaveRequest.LeaveRequestSeasons[j].LeaveRequestPriorities, seasons[i].Slots);\n\n for (var h = 0; h < seasons[i].Configurations.length; h++) {\n if (seasons[i].Configurations[h].Id == leaveRequest.LeaveRequestSeasons[j].ConfigurationId) {\n leaveRequest.LeaveRequestSeasons[j].Configuration = seasons[i].Configurations[h];\n }\n }\n }\n }\n }\n\n $scope.LeaveRequest = leaveRequest;\n }\n\n function setupMockLeaveRequestPriorities(priorities, slots) {\n for (var i = 0; i < priorities.length; i++) {\n for (var j = 0; j < priorities[i].LeaveRequestPriorityPeriods.length; j++) {\n for (var h = 0; h < priorities[i].LeaveRequestPriorityPeriods[j].LeaveRequestPrioritySlots.length; h++) {\n var tempOrderNo = priorities[i].LeaveRequestPriorityPeriods[j].LeaveRequestPrioritySlots[h].OrderNo; //need clone the priority slot to fix conflicts with onder numbers\n\n priorities[i].LeaveRequestPriorityPeriods[j].LeaveRequestPrioritySlots[h] = JSON.parse(JSON.stringify(findSlot(priorities[i].LeaveRequestPriorityPeriods[j].LeaveRequestPrioritySlots[h], slots)));\n priorities[i].LeaveRequestPriorityPeriods[j].LeaveRequestPrioritySlots[h].OrderNo = tempOrderNo;\n } //need clone the priority slot to fix conflicts with onder numbers\n\n\n priorities[i].LeaveRequestPriorityPeriods[j].MockLeaveRequestPrioritySlots = JSON.parse(JSON.stringify(priorities[i].LeaveRequestPriorityPeriods[j].LeaveRequestPrioritySlots));\n }\n }\n }\n\n function findSlot(value, slots) {\n var temp = null;\n\n for (var i = 0; i < slots.length; i++) {\n if (slots[i].Id == value.Id) {\n temp = slots[i];\n }\n }\n\n return temp;\n }\n\n function showHelp() {\n $uibModal.open({\n templateUrl: 'views/LeaveRequest/dlgLeaveRequestInstructions.html',\n controller: 'LeaveRequestInstructionsCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {}\n });\n }\n\n function initializeNewRequest(seasons) {\n for (var i = 0; i < seasons.length; i++) {\n var leaveRequestSeason = seasons[i];\n leaveRequestSeason.SeasonId = leaveRequestSeason.Id;\n var flexLeaveRequestPriority = {\n Type: \"Any\",\n Priority: 1000,\n LeaveRequestPriorityPeriods: []\n };\n var configurationDays = [];\n\n for (var j = 0; j < seasons[i].Configurations.length; j++) {\n configurationDays.push(seasons[i].Configurations[j].Days);\n }\n\n leaveRequestSeason.Days = configurationDays.unique();\n leaveRequestSeason.HasSpecificCombinations = false;\n leaveRequestSeason.LeaveRequestPriorities = [flexLeaveRequestPriority];\n $scope.LeaveRequest.LeaveRequestSeasons.push(leaveRequestSeason);\n }\n }\n\n function IsValidLeaveRequest() {\n var isValid = true;\n\n if (!$scope.LeaveRequest.RequestNoleave) {\n //Validate only if Requested Leave\n if ($scope.LeaveRequest && !$scope.invalidSelectedLeaveDays) {\n for (var i = 0; i < $scope.LeaveRequest.LeaveRequestSeasons.length; i++) {\n for (var j = 0; j < $scope.LeaveRequest.LeaveRequestSeasons[i].LeaveRequestPriorities.length; j++) {\n if ($scope.LeaveRequest.LeaveRequestSeasons[i].LeaveRequestPriorities[j].HasInvalidPeriod) {\n isValid = false;\n break;\n }\n }\n\n if (!$scope.LeaveRequest.LeaveRequestSeasons[i].Configuration) {\n isValid = false;\n break;\n }\n }\n } else {\n isValid = false;\n }\n }\n\n return isValid;\n }\n\n $scope.updateLeaveRequestSeason = updateLeaveRequestSeason;\n $scope.showCombo = false;\n $scope.radioConfigurationModel = null;\n $scope.sendRequest = sendRequest;\n $scope.addComment = addComment;\n\n function addComment(request) {\n request.Comments = \" \";\n }\n\n function sendRequest() {\n //Request No Leave: Clear any selected values\n if ($scope.LeaveRequest.RequestNoleave) {\n $scope.LeaveRequest.LeaveRequestSeasons = null;\n }\n\n progressBarBox(true);\n LeaveRequestFactory.saveLeaveRequest($scope.LeaveRequest, onSuccessSendRequest, onErrorSendRequest);\n }\n\n function onSuccessSendRequest(data) {\n progressBarBox(false);\n\n if (data.data.success == true) {\n ShowSuccessMessage();\n } else {\n ShowErrorMessage();\n }\n }\n\n function onErrorSendRequest(data) {\n progressBarBox(false);\n ShowErrorMessage();\n }\n\n function ShowSuccessMessage() {\n var closeDateStr = moment($scope.LeaveRequestInformation.CloseDate).format('Do of MMMM');\n bootbox.alert({\n title: \"
Success
\",\n message: \"You have successfully submitted your leave request. You can modify your leave request untill the \" + closeDateStr + \".\",\n callback: function callback() {\n $route.reload();\n }\n });\n }\n\n function ShowErrorMessage() {\n bootbox.alert({\n title: \"
Error
\",\n message: \"Failed to send your leave request. Please try again later\",\n callback: function callback() {\n $route.reload();\n }\n });\n }\n\n function progressBarBox(isOpen) {\n if (isOpen) {\n bootbox.dialog({\n closeButton: false,\n message: '
Please wait...
' //title: \"Please wait...\"\n\n });\n } else {\n bootbox.hideAll();\n }\n }\n /* function setupView() {\r\n if (!UserFactory.isLoggedIn()) {\r\n $location.path(\"/login\");\r\n }*/\n //$scope.sortableOptions['ui-floating'] = true;\n\n\n function updateLeaveRequestSeason(season) {\n season.ConfigurationId = season.Configuration.Id;\n\n for (var i = 0; i < season.LeaveRequestPriorities.length; i++) {\n for (var j = 0; j < season.Configuration.Periods.length; j++) {\n season.Configuration.Periods[j].ConfigurationPeriodId = season.Configuration.Periods[j].Id;\n }\n\n season.LeaveRequestPriorities[i].LeaveRequestPriorityPeriods = JSON.parse(JSON.stringify(season.Configuration.Periods));\n }\n\n var totalDays = 0;\n var hasConfig = true;\n\n for (var i = 0; i < $scope.LeaveRequest.LeaveRequestSeasons.length; i++) {\n totalDays = totalDays + ($scope.LeaveRequest.LeaveRequestSeasons[i].Configuration && $scope.LeaveRequest.LeaveRequestSeasons[i].Configuration.Days ? $scope.LeaveRequest.LeaveRequestSeasons[i].Configuration.Days : 0);\n hasConfig = hasConfig && $scope.LeaveRequest.LeaveRequestSeasons[i].Configuration;\n }\n\n if (totalDays > $scope.LeaveRequestInformation.LeaveDays) {\n $scope.invalidSelectedLeaveDays = true;\n bootbox.alert(\"

Warning!

You are entilted to \" + $scope.LeaveRequestInformation.LeaveDays + \" leave days but you have selected a combination of \" + totalDays + \" days. Please proceed with the necessary changes.\");\n } else if (!$scope.QualificationGroup.RequestLessDays && totalDays < $scope.LeaveRequestInformation.LeaveDays) {\n $scope.invalidSelectedLeaveDays = true;\n\n if (hasConfig) {\n bootbox.alert(\"

Warning!

You are entilted to \" + $scope.LeaveRequestInformation.LeaveDays + \" leave days but you have selected a combination of \" + totalDays + \" days. Please proceed with the necessary changes.\");\n }\n } else {\n $scope.invalidSelectedLeaveDays = false;\n }\n }\n\n function getRandomBorderColor(season) {\n var cssClass = \"border-left-green\";\n\n if (!season.Configuration) {\n cssClass = \"border-left-orange\";\n }\n\n return cssClass;\n }\n\n function getRandomTextColor(season) {\n var cssClass = \"text-green\";\n\n if (!season.Configuration) {\n cssClass = \"text-orange\";\n }\n\n return cssClass;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('LeaveRequestFactory', LeaveRequestFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name LeaveRequestFactory\r\n * @description \r\n * Get Leave Request Configuration Data and submit new Leave Request\r\n * @ngInject\r\n */\n\n function LeaveRequestFactory(GenericService, $http, $q, apiUrl) {\n var service = {\n getConfigurationDetails: getConfigurationDetails,\n saveLeaveRequestInformation: saveLeaveRequestInformation,\n getLeaveRequestInformation: getLeaveRequestInformation,\n saveLeaveRequest: saveLeaveRequest\n };\n /**\r\n * Initialize the LeaveRequestInformation\r\n * @memberof LeaveRequestFactory\r\n */\n\n function LeaveRequestInformation() {}\n\n var objType = 'LeaveRequestInformation';\n var objCallback = LeaveRequestInformation;\n var leaveRequestApiURL = apiUrl + '/LeaveRequest';\n /**\r\n * Get the LeaveRequestInformation and the qualification Group\r\n * @memberof LeaveRequestFactory\r\n * @param {function} callback an on success callback function\r\n * @param {function} errorCallback an on error callback function\r\n */\n\n function getConfigurationDetails(callback, errorCallback) {\n return $http.get(leaveRequestApiURL, {\n 'Content-Type': 'application/json'\n }).then(function (responseData) {\n if (responseData && responseData.data && responseData.data.data && responseData.data.data.LeaveRequestInformation) {\n saveLeaveRequestInformation(responseData.data.data.LeaveRequestInformation);\n }\n\n callback(responseData);\n })[\"catch\"](errorCallback);\n }\n\n function saveLeaveRequest(request, callback, errorCallback) {\n var cleanRequest = angular.toJson(request);\n return $http.post(leaveRequestApiURL, cleanRequest, {\n 'Content-Type': 'application/json'\n }).then(function (responseData) {\n if (responseData && responseData.data && responseData.data.data && responseData.data.data.LeaveRequestInformation) {\n saveLeaveRequestInformation(responseData.data.data.LeaveRequestInformation);\n }\n\n callback(responseData);\n })[\"catch\"](errorCallback);\n }\n /**\r\n * Save the leave Request Information Object in local storage\r\n * @memberof LeaveRequestFactory\r\n * @param {object} leaveRequestInformation a leaveRequestInformation\r\n */\n\n\n function saveLeaveRequestInformation(leaveRequestInformation) {\n GenericService.saveOne(leaveRequestInformation, objType, objCallback);\n }\n /**\r\n * Save the leave Request Information Object in local storage\r\n * @memberof LeaveRequestFactory \r\n * @returns {object} leaveRequestInformation \r\n */\n\n\n function getLeaveRequestInformation() {\n return GenericService.getOne(objType, objCallback);\n }\n /*function postProposal(proposal){\r\n return $http.post(apiUrl + '/bucket/PostProposal/', proposal, { 'Content-Type' : 'application/json' });\r\n }\r\n */\n\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('LeaveRequestInstructionsCtrl', LeaveRequestInstructionsCtrl);\n /**\r\n * @memberof PilotReports\r\n * @ngdoc controller\r\n * @name LeaveRequestInstructionsCtrl\r\n * @description \r\n * Get the Leave Request Instructions\r\n * @ngInject\r\n */\n\n function LeaveRequestInstructionsCtrl($scope, $uibModalInstance) {\n $scope.page = 1;\n $scope.cancel = cancel;\n $scope.nextPage = nextPage;\n $scope.previousPage = previousPage;\n $scope.instructionPages = 3;\n /**\r\n * Goes to the next page of leave instructions\r\n * @memberof LeaveRequestInstructionsCtrl\r\n */\n\n function nextPage() {\n $scope.page = $scope.page + 1;\n normalizePage();\n }\n /**\r\n * Goes to the previous page of leave instructions\r\n * @memberof LeaveRequestInstructionsCtrl\r\n */\n\n\n function previousPage() {\n $scope.page = $scope.page - 1;\n normalizePage();\n }\n /**\r\n * Normalize the page number if it is out of range\r\n * @memberof LeaveRequestInstructionsCtrl\r\n */\n\n\n function normalizePage() {\n if ($scope.page > $scope.instructionPages || $scope.page < 1) {\n $scope.page = 1;\n }\n }\n /**\r\n * Close the modal\r\n * @memberof LeaveRequestInstructionsCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close('close');\n }\n\n ;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('specificCombinations', SpecificCombinations);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name SpecificCombinations\r\n * @restrict E\r\n * @description\r\n * Implementation of Specific Combinations\r\n *\r\n * Initialize the Specific Combinations of a season\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function SpecificCombinations($filter) {\n function link(scope, element, attrs) {\n scope.IsEditEnabled = false;\n scope.selectEditablePeriod = selectEditablePeriod;\n scope.updateEditablePeriod = updateEditablePeriod;\n scope.removeSpecificCombination = removeSpecificCombination;\n scope.addNewSpecificCombination = addNewSpecificCombination;\n scope.getBorderClass = getBorderClass;\n scope.selectedSlotTemp = null;\n scope.isDisabled = isDisabled;\n scope.specificCombinations = $filter('filter')(scope.seasonRequests, {\n Type: 'All'\n });\n scope.sortableOptions = {\n handle: '> .row .myHandle',\n update: function update(e, ui) {},\n stop: function stop(e, ui) {\n recalculatePriorities();\n }\n };\n\n function recalculatePriorities() {\n for (var i = 0; i < scope.specificCombinations.length; i++) {\n scope.specificCombinations[i].Priority = i + 1;\n }\n }\n\n function selectEditablePeriod(period, request) {\n if (!period.isEditable) {\n resetEditablePeriods();\n\n if (period.LeaveRequestPrioritySlots && period.LeaveRequestPrioritySlots.length > 0) {\n scope.selectedSlotTemp = period.LeaveRequestPrioritySlots[0];\n } else {\n scope.selectedSlotTemp = null;\n }\n\n scope.selectedRequestTemp = request;\n scope.selectedSlotDaysTemp = period.Days;\n period.isEditable = true;\n scope.IsEditEnabled = true;\n } else {\n resetEditablePeriods();\n }\n }\n\n function getBorderClass(request) {\n var hasEmptyFields = false;\n var hasFilledFields = false;\n var cssClass = \"\";\n\n for (var i = 0; i < request.LeaveRequestPriorityPeriods.length; i++) {\n hasEmptyFields = hasEmptyFields || !request.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots || request.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots.length == 0;\n hasFilledFields = hasFilledFields || !(!request.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots || request.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots.length == 0);\n }\n\n if (hasEmptyFields && hasFilledFields) {\n cssClass = 'specific-combination-orange';\n request.HasInvalidPeriod = true;\n } else if (hasEmptyFields && !hasFilledFields) {\n cssClass = 'specific-combination-blue';\n request.HasInvalidPeriod = false;\n } else if (hasFilledFields && !hasEmptyFields) {\n cssClass = 'specific-combination-green';\n request.HasInvalidPeriod = false;\n }\n\n return cssClass;\n }\n\n function isDisabled(slot) {\n var CSSclass = \"\";\n\n if (scope.selectedRequestTemp) {\n for (var i = 0; i < scope.selectedRequestTemp.LeaveRequestPriorityPeriods.length; i++) {\n if (scope.selectedRequestTemp.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots && scope.selectedRequestTemp.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots.length > 0 && (scope.selectedRequestTemp.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots[0].Id == slot.Id || scope.selectedRequestTemp.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots[0].EndDay >= slot.StartDay && scope.selectedRequestTemp.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots[0].StartDay <= slot.EndDay)) {\n CSSclass = \"disabled\";\n break;\n }\n }\n }\n\n return CSSclass;\n }\n\n function resetEditablePeriods() {\n for (var i = 0; i < scope.seasonRequests.length; i++) {\n for (var j = 0; j < scope.seasonRequests[i].LeaveRequestPriorityPeriods.length; j++) {\n scope.seasonRequests[i].LeaveRequestPriorityPeriods[j].isEditable = false;\n }\n }\n\n scope.IsEditEnabled = false;\n }\n\n function updateEditablePeriod(slot) {\n for (var i = 0; i < scope.seasonRequests.length; i++) {\n for (var j = 0; j < scope.seasonRequests[i].LeaveRequestPriorityPeriods.length; j++) {\n if (scope.seasonRequests[i].LeaveRequestPriorityPeriods[j].isEditable && slot && slot.Code) {\n scope.seasonRequests[i].LeaveRequestPriorityPeriods[j].LeaveRequestPrioritySlots = [slot];\n }\n }\n }\n\n resetEditablePeriods();\n }\n\n function removeSpecificCombination(priority) {\n var indexOfRemovedObj = null;\n\n for (var i = 0; i < scope.seasonRequests.length; i++) {\n if (scope.seasonRequests[i].Priority == priority) {\n indexOfRemovedObj = i;\n }\n }\n\n if (indexOfRemovedObj != null) {\n scope.seasonRequests.splice(indexOfRemovedObj, 1);\n scope.specificCombinations = $filter('filter')(scope.seasonRequests, {\n Type: 'All'\n });\n recalculatePriorities();\n }\n }\n\n function addNewSpecificCombination() {\n var newSpecificCombinationPriority = 1;\n\n if (scope.specificCombinations && scope.specificCombinations.length > 0) {\n newSpecificCombinationPriority = scope.specificCombinations.length + 1;\n }\n\n var newObj = {\n Type: \"All\",\n Priority: newSpecificCombinationPriority,\n LeaveRequestPriorityPeriods: []\n };\n scope.seasonRequests.push(newObj);\n updateLeaveRequestSeason();\n scope.specificCombinations = $filter('filter')(scope.seasonRequests, {\n Type: 'All'\n });\n scope.IsEditEnabled = false;\n }\n\n function updateLeaveRequestSeason() {\n scope.seasonConfiguration.ConfigurationId = scope.seasonConfiguration.Configuration.Id;\n\n for (var i = 0; i < scope.seasonRequests.length; i++) {\n for (var j = 0; j < scope.seasonConfiguration.Configuration.Periods.length; j++) {\n scope.seasonConfiguration.Configuration.Periods[j].ConfigurationPeriodId = scope.seasonConfiguration.Configuration.Periods[j].Id;\n }\n\n if (scope.seasonRequests[i].LeaveRequestPriorityPeriods && scope.seasonRequests[i].LeaveRequestPriorityPeriods.length == 0) {\n scope.seasonRequests[i].LeaveRequestPriorityPeriods = JSON.parse(JSON.stringify(scope.seasonConfiguration.Configuration.Periods));\n }\n }\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/LeaveRequest/specificCombinations.tpl.html',\n scope: {\n seasonConfiguration: '<',\n seasonRequests: '=',\n editable: '<'\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.service(\"CabinAPIService\", CabinAPIService);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc service\r\n * @name CabinAPIService\r\n * @description \r\n * Api login service\r\n * @ngInject\r\n */\n\n function CabinAPIService($http, $q, apiUrl) {\n return {\n /**\r\n * Login to Pilot Api\r\n * @memberof PilotAPIService\r\n * @param {number} username\r\n * @returns {string} password\r\n */\n login: function login(token) {\n var call = $q.defer();\n var bearer = \"Bearer \" + token;\n $http.post(apiUrl + '/login', {}, {\n 'headers': {\n 'Content-Type': 'application/json',\n 'Authorization': bearer\n }\n }).then(function (responseData) {\n call.resolve(responseData);\n }, function (err) {\n call.reject(err);\n });\n return call.promise;\n }\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('LoginCtrl', LoginCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name LoginCtrl\r\n * @description \r\n * Manages the login view\r\n * @ngInject\r\n */\n\n function LoginCtrl($location, $scope, localStorageMD5Service, UserFactory) {\n $scope.isSupported = isSupported;\n $scope.isSecure = UserFactory.isSecure();\n $scope.isLoggingIn = false;\n $scope.formData = {};\n $scope.goSecure = goSecure;\n $scope.errorName = \"\";\n $scope.goNormal = goNormal;\n $scope.moreInfo = false; // used to show more info on the page\n\n $scope.toggleMoreInfo = toggleMoreInfo;\n $scope.processForm = processForm;\n $scope.resetDevice = resetDevice;\n $scope.resetUser = resetUser;\n $scope.loginFailedAttemps = UserFactory.getLoginFailedAttemps();\n /**\r\n * Informs you if local storage is supported \r\n * @memberof LoginCtrl\r\n * @returns {boolean} isSupported\r\n */\n\n function isSupported() {\n return localStorageMD5Service.isSupported;\n }\n /**\r\n * Converts application to normal local storage mode \r\n * @memberof LoginCtrl\r\n */\n\n\n function goNormal() {\n var path = window.location.href;\n path = path.replace('?secure', '');\n window.location = path;\n location.reload();\n }\n /**\r\n * Proccess login form and try to login\r\n * @memberof LoginCtrl\r\n */\n\n\n function goSecure() {\n var path = window.location.href;\n path = path + '?secure';\n window.location = path;\n location.reload();\n }\n /**\r\n * Show More info\r\n * @memberof LoginCtrl\r\n */\n\n\n function toggleMoreInfo() {\n $scope.moreInfo = !$scope.moreInfo;\n }\n /**\r\n * Proccess login form and try to login\r\n * @memberof LoginCtrl\r\n */\n\n\n function processForm() {\n $scope.loginFailedAttemps = UserFactory.getLoginFailedAttemps();\n\n if ($scope.loginFailedAttemps > 3) {\n localStorageMD5Service.remove('failedLoginAttemps');\n resetUser();\n } else {\n $scope.isLoggingIn = true;\n UserFactory.azlogin(afterLoginSuccess, afterLoginError, afterLoginFinal)[\"catch\"](function (error) {\n //console.error(\"An error occurred during login:\", error);\n afterLoginError();\n });\n }\n }\n /**\r\n * AfterLoginSuccess\r\n * @memberof LoginCtrl\r\n */\n\n\n function afterLoginSuccess() {\n $scope.isLoggingIn = false; // load main page\n\n $scope.errorName = \"\";\n $location.path(\"/\");\n }\n /**\r\n * afterLoginFinal\r\n * @memberof LoginCtrl\r\n */\n\n\n function afterLoginFinal() {\n $scope.isLoggingIn = false;\n }\n /**\r\n * AfterLoginError\r\n * @memberof LoginCtrl\r\n */\n\n\n function afterLoginError(response) {\n $scope.isLoggingIn = false; // display an error message\n\n if (response && response.status == 401) {\n if (response.data && response.data.Message) $scope.errorName = response.data.Message.length > 1 ? response.data.Message : \"You are not authorized to use this CLS Cabin app\";else $scope.errorName = \"You are not authorized to use this CLS Cabin app\";\n } else if (response && response.status == 404) {\n $scope.errorName = \"Could not reach the remote server for authentication. Please connect to the Internet and try again.\";\n } else {\n $scope.errorName = \"An error occured during authentication. Please make sure you are connected to the Internet and try again.\";\n }\n\n ;\n }\n /**\r\n * Redirect to reset view\r\n * @memberof LoginCtrl\r\n */\n\n\n function resetDevice() {\n $location.path(\"/reset\");\n }\n /**\r\n * Sign out\r\n * @memberof LoginCtrl\r\n */\n\n\n function resetUser() {\n UserFactory.azSignOut();\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('UserFactory', UserFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name UserFactory\r\n * @description \r\n * Add, Update, Delete and Get User.\r\n * @ngInject\r\n */\n //function UserFactory(localStorageMD5Service, CabinAPIService, DataCleanerFactory, GenericService, LogService, $http, apiUrl) {\n\n function UserFactory(LogService, localStorageMD5Service, $http, apiUrl, CabinAPIService, DataCleanerFactory, GenericService, azureADAuth) {\n var msalConfig = {\n auth: azureADAuth,\n cache: {\n cacheLocation: \"sessionStorage\",\n // This configures where your cache will be stored\n storeAuthStateInCookie: false // Set this to \"true\" if you are having issues on IE11 or Edge\n\n }\n };\n var myMSALObj = new msal.PublicClientApplication(msalConfig);\n var username = null;\n myMSALObj.handleRedirectPromise().then(handleResponse)[\"catch\"](function (error) {\n console.error(error);\n LogService.error(error, 'Failed to handle redirect Login');\n });\n\n function handleResponse(response) {\n if (response !== null) {\n username = response.account.username;\n } else {\n selectAccount();\n }\n }\n\n function selectAccount() {\n /**\r\n * See here for more info on account retrieval: \r\n * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md\r\n */\n var currentAccounts = myMSALObj.getAllAccounts();\n\n if (currentAccounts.length === 0) {\n return;\n } else if (currentAccounts.length > 0) {\n username = currentAccounts[0].username;\n }\n }\n /**\r\n * Initialize the User\r\n * @memberof UserFactory\r\n */\n\n\n function User() {\n this.id = null;\n this.aimsId = null;\n this.name = null;\n this.shortname = null;\n this.position = null;\n this.hashedPwd = null;\n this.token = null;\n this.syncDialogLastDt = null;\n this.getDescription = getDescription;\n this.tokenExtended = false;\n }\n\n var service = {\n getUser: getUser,\n setUser: setUser,\n isSecure: isSecure,\n isLoggedIn: isLoggedIn,\n clearActiveUser: clearActiveUser,\n setActiveUser: setActiveUser,\n login: login,\n extendToken: extendToken,\n azlogin: azlogin,\n azSignOut: azSignOut,\n getLoginFailedAttemps: getLoginFailedAttemps,\n newLoginFailedAttemp: newLoginFailedAttemp\n };\n var objType = 'user';\n var objCallback = User; //Object Functions\n\n function getDescription() {\n if (this.aimsid == null && this.name == null) return '-null-';else return (this.aimsid || '?') + ' - ' + (this.name || '?');\n } //Factory Functions\n\n /**\r\n * Get User \r\n * @memberof UserFactory\r\n * @returns {Object} User\r\n */\n\n\n function getUser() {\n return GenericService.getOne(objType, objCallback);\n }\n /**\r\n * Save User \r\n * @memberof UserFactory\r\n * @param {Object} User\r\n */\n\n\n function setUser(user) {\n GenericService.saveAll(user, objType, objCallback);\n }\n /**\r\n * Checks if local storage is on secure mode \r\n * @memberof UserFactory\r\n * @param {boolean} isSecure\r\n */\n\n\n function isSecure() {\n return localStorageMD5Service.isSecure();\n }\n /**\r\n * Check if user exists and he has logged in\r\n * @memberof UserFactory\r\n * @param {boolean} isLoggedIn\r\n */\n\n\n function isLoggedIn() {\n var user = null;\n\n try {\n user = getUser();\n\n if (user != null) {\n var act = localStorageMD5Service.get('active');\n\n if (!act || !act.aimsId || act.aimsId != user.aimsId) {\n user = null;\n }\n } else user = null;\n } catch (e) {\n user = null;\n }\n\n return user;\n }\n /**\r\n * Clear Active User\r\n * @memberof UserFactory\r\n */\n\n\n function clearActiveUser() {\n localStorageMD5Service.remove('active');\n }\n /**\r\n * Save Active User \r\n * @memberof UserFactory\r\n * @param {Object} User\r\n */\n\n\n function setActiveUser(user) {\n if (user != null && user.aimsId != null) {\n var value = {\n aimsId: user.aimsId\n };\n localStorageMD5Service.set('active', value);\n }\n }\n\n function azlogin(onsuccess, onerror, onfinally) {\n return new Promise(function (resolve, reject) {\n var loginRequest = {\n scopes: [\"User.Read\"]\n };\n var silentRequest = {\n scopes: [\"openid\", \"profile\", \"User.Read\"],\n redirectUri: \"http://localhost:3000/blank.html\"\n };\n\n if (username == null) {\n myMSALObj.loginRedirect(loginRequest);\n resolve(); // Resolve immediately for redirect scenario\n } else {\n silentRequest.account = myMSALObj.getAccountByUsername(username);\n var token = null;\n myMSALObj.acquireTokenSilent(silentRequest).then(function (tokenResponse) {\n if (!tokenResponse.idToken) {\n LogService.error('response.idToken is undefined');\n newLoginFailedAttemp(); // Run newLoginFailedAttemp() if idToken is undefined\n\n reject(new Error('Token is not available')); // Reject the promise\n } else {\n token = tokenResponse.idToken;\n localStorageMD5Service.remove('failedLoginAttemps');\n login(token, onsuccess, onerror, onfinally);\n resolve(); // Resolve after successful login\n }\n })[\"catch\"](function (error) {\n if (error instanceof msal.InteractionRequiredAuthError) {\n LogService.error(error, 'Fallback to interaction when silent call fails'); // Handle the redirection process error here if needed\n\n myMSALObj.acquireTokenRedirect(silentRequest).then(function () {\n // Continue with the process after successful redirection\n resolve();\n })[\"catch\"](function (redirectError) {\n LogService.error(redirectError, 'Error during redirection');\n newLoginFailedAttemp(); // Run newLoginFailedAttemp() for redirection errors\n\n reject(redirectError); // Reject the promise with the redirection error\n });\n } else {\n LogService.error(error, 'Failed to acquire token silently');\n newLoginFailedAttemp(); // Run newLoginFailedAttemp() for other errors\n\n reject(error); // Reject the promise with the error\n }\n });\n }\n });\n }\n\n function azSignOut() {\n /**\r\n * You can pass a custom request object below. This will override the initial configuration. For more information, visit:\r\n * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request\r\n */\n var logoutRequest = {\n account: myMSALObj.getAccountByUsername(username),\n postLogoutRedirectUri: window.location.href\n };\n myMSALObj.logoutRedirect(logoutRequest);\n }\n /**\r\n * Add code to try to login locally if remote login fails with a 404 or timeout\r\n * @memberof UserFactory\r\n * @param {string} token\r\n * @param {function} onsuccess callback function if the call is a success\r\n * @param {function} onerror callback function if the call failed\r\n * @param {function} onfinally callback function that runs on the end\r\n */\n\n\n function login(token, onsuccess, onerror, onfinally) {\n clearActiveUser();\n var q = CabinAPIService.login(token);\n q.then(function (response) {\n // if the user that tries to log in is different than the last\n // logged in user, then reset all stored server data\n if (getUser() != null) {\n if (getUser().aimsId.toString() != response.data.data.aimsId.toString()) {\n DataCleanerFactory.deleteAllData();\n }\n } // delete any flights created locally, that do not have any local\n // reports\n\n\n DataCleanerFactory.deleteOrphanedLocalFlights(); // assign the logged in user\n\n var user = response.data.data;\n setUser(user);\n setActiveUser(user);\n\n if (typeof onsuccess == \"function\") {\n onsuccess();\n }\n });\n q[\"catch\"](function (response) {\n if (typeof onerror == \"function\") {\n onerror(response);\n }\n });\n q[\"finally\"](function (response) {\n if (typeof onfinally == \"function\") {\n onfinally();\n }\n });\n return q;\n }\n /**\r\n * the function that extends the token for limited time if a user forgot their password\r\n * @memberof UserFactory\r\n * @param {function} onsuccess callback function if the call is a success\r\n * @param {function} onerror callback function if the call failed\r\n */\n\n\n function extendToken(onsuccess, onerror) {\n var user = getUser();\n $http.post(apiUrl + '/login/extendtoken', {\n 'Token': user.token\n }, {\n 'Content-Type': 'application/json'\n }).then(function (response) {\n user.token = response.data.data;\n user.tokenExtended = true;\n setUser(user);\n setActiveUser(user);\n\n if (typeof onsuccess == \"function\") {\n onsuccess();\n }\n })[\"catch\"](function (response) {\n if (typeof onerror == \"function\") {\n onerror(response);\n }\n });\n }\n\n function getLoginFailedAttemps() {\n var failedLoginAttemps = localStorageMD5Service.get('failedLoginAttemps');\n\n if (failedLoginAttemps) {\n return failedLoginAttemps;\n } else {\n return 0;\n }\n }\n\n function newLoginFailedAttemp() {\n var value = 1;\n var failedLoginAttemps = localStorageMD5Service.get('failedLoginAttemps');\n\n if (failedLoginAttemps && failedLoginAttemps !== \"null\") {\n var attempsToNumber = Number(failedLoginAttemps);\n value = value + attempsToNumber;\n }\n\n localStorageMD5Service.set('failedLoginAttemps', value);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('LuggageComplianceFactory', LuggageComplianceFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name LuggageComplianceFactory\r\n * @description \r\n * Add, Update, Delete and Get Luggage Compliance per passenger-flight\r\n * @ngInject\r\n */\n\n function LuggageComplianceFactory(GenericService, $http, apiUrl, $timeout) {\n var objType = 'LuggageCompliance';\n var objCallback = LuggageCompliance;\n /**\r\n * Initialize the Passenger Incident\r\n * @memberof LuggageComplianceFactory\r\n */\n\n function LuggageCompliance() {\n this.GetId = GetId;\n this.isSynced = false;\n }\n\n var submitResponseObj = {\n success: false,\n message: ''\n };\n var service = {\n setAllLuggageComplianceToStorage: setAllLuggageComplianceToStorage,\n setLuggageComplianceToStorage: setLuggageComplianceToStorage,\n saveLuggageComplianceToStorage: saveLuggageComplianceToStorage,\n getLuggageComplianceFromStorage: getLuggageComplianceFromStorage,\n updateLuggageCompliance: updateLuggageCompliance,\n saveLuggageCompliance: saveLuggageCompliance,\n getLuggageComplianceByFlightId: getLuggageComplianceByFlightId,\n getPassengerLuggageCompliance: getPassengerLuggageCompliance,\n removeLuggageCompliance: removeLuggageCompliance,\n removePendingsLuggageCompliance: removePendingsLuggageCompliance,\n removeLuggageComplianceByFlightId: removeLuggageComplianceByFlightId,\n deleteAllLuggageComplianceReportsByFlightId: deleteAllLuggageComplianceReportsByFlightId,\n submitLuggageCompliance: submitLuggageCompliance,\n syncResultFormat: syncResultFormat,\n updateLuggageComplianceStorage: updateLuggageComplianceStorage,\n saveFlightIsCompliantToStorage: saveFlightIsCompliantToStorage,\n getFlightCompliantStatus: getFlightCompliantStatus,\n cleanOldData: cleanOldData\n };\n\n function GetId() {\n return this.LocalId;\n }\n /**\r\n * Save All Luggage Compliance Passengers\r\n * @param {array} objList \r\n */\n\n\n function setAllLuggageComplianceToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Add or Remove a Luggage Compliance Report\r\n * @param {object} luggageComplianceReport\r\n */\n\n\n function setLuggageComplianceToStorage(luggageComplianceReport) {\n var report = getPassengerLuggageCompliance(luggageComplianceReport.FlightId, luggageComplianceReport.UCI);\n\n if (report && !luggageComplianceReport.isChecked) {\n removeLuggageCompliance(report.LocalId);\n } else if (luggageComplianceReport.isChecked) {\n saveLuggageCompliance(luggageComplianceReport);\n }\n }\n /**\r\n * Add a Luggage Compliance Report if it doesn't already exist, when this function is executed in loop it needs the index of report to prevent same LocalIds.\r\n * @param {object} luggageComplianceReport\r\n * @param {object} reportIndex\r\n */\n\n\n function saveLuggageComplianceToStorage(luggageComplianceReport, reportIndex) {\n if (!reportIndex) {\n reportIndex = 0;\n }\n\n var report = getPassengerLuggageCompliance(luggageComplianceReport.FlightId, luggageComplianceReport.UCI);\n\n if (!report) {\n //use reportIndex to prevent same LocalId value\n saveLuggageCompliance(luggageComplianceReport, reportIndex);\n }\n }\n /**\r\n * Add a Luggage Compliance Report for whole flight if it doesn't already exist\r\n * @param {object} luggageComplianceReport\r\n */\n\n\n function saveFlightIsCompliantToStorage(luggageComplianceReport) {\n var luggageComplianceReports = getLuggageComplianceByFlightId(luggageComplianceReport.FlightId);\n var report = luggageComplianceReports.find(function (x) {\n return x.IsFlightCompliant === true;\n });\n\n if (!report) {\n saveLuggageCompliance(luggageComplianceReport);\n }\n }\n /**\r\n * Get all luggage compliance reports of a flight\r\n * @param {number} flightId \r\n */\n\n\n function getLuggageComplianceByFlightId(flightId) {\n var allReports = getLuggageComplianceFromStorage();\n var flightReports = allReports.filter(function (x) {\n return x.FlightId == flightId;\n });\n return flightReports;\n }\n\n ;\n\n function getFlightCompliantStatus(flightId) {\n var returnStatus = {\n IsFlightCompliant: false,\n Status: '',\n HasPendingsReports: false\n };\n var luggageComplianceReports = getLuggageComplianceByFlightId(flightId);\n var flightCompliantReport = luggageComplianceReports.find(function (x) {\n return x.IsFlightCompliant;\n });\n\n if (flightCompliantReport) {\n returnStatus.IsFlightCompliant = true;\n\n if (flightCompliantReport.isSynced) {\n returnStatus.Status = 'synced';\n } else {\n returnStatus.Status = 'pending';\n }\n }\n\n returnStatus.HasPendingsReports = luggageComplianceReports.some(function (s) {\n return !s.IsFlightCompliant && !s.isSynced;\n });\n return returnStatus;\n }\n /**\r\n * Get all luggage compliance reports\r\n */\n\n\n function getLuggageComplianceFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Get luggage compliance report for a specific passenger in a specific flight\r\n * @param {number} flightId \r\n * @param {number} uci \r\n */\n\n\n function getPassengerLuggageCompliance(flightId, uci) {\n var luggageComplianceReports = getLuggageComplianceByFlightId(flightId);\n var passengerReport = luggageComplianceReports.find(function (x) {\n return x.UCI == uci;\n });\n return passengerReport;\n }\n /**\r\n * Update a luggage compliance report (Search by FlightId-UCI)\r\n * @param {object} luggageComplianceReport \r\n */\n\n\n function updateLuggageCompliance(luggageComplianceReport) {\n GenericService.save(luggageComplianceReport, objType, objCallback);\n }\n /**\r\n * Create a new luggage compliance report\r\n * @param {object} luggageComplianceReport \r\n */\n\n\n function saveLuggageCompliance(luggageComplianceReport, reportIndex) {\n if (!reportIndex) {\n reportIndex = 0;\n }\n\n luggageComplianceReport.LocalId = moment().valueOf() + reportIndex;\n luggageComplianceReport.isSynced = false;\n GenericService.add(luggageComplianceReport, objType, objCallback);\n }\n /**\r\n * Remove customer event from storage\r\n * @param {number} luggageComplianceReportId \r\n */\n\n\n function removeLuggageCompliance(luggageComplianceReportId) {\n GenericService.remove(luggageComplianceReportId, objType, objCallback);\n }\n /**\r\n * Remove all pendings luggage compliance reports in a flight from storage\r\n * @param {number} flightId \r\n */\n\n\n function removePendingsLuggageCompliance(flightId) {\n var pendingReports = getLuggageComplianceByFlightId(flightId).filter(function (x) {\n return !x.isSynced;\n });\n\n if (pendingReports) {\n pendingReports.forEach(function (unsyncedReport) {\n removeLuggageCompliance(unsyncedReport.LocalId);\n });\n }\n }\n /**\r\n * Remove all luggage compliance reports in a flight from storage\r\n * @param {number} flightId \r\n */\n\n\n function removeLuggageComplianceByFlightId(flightId) {\n var reports = getLuggageComplianceByFlightId(flightId);\n\n if (reports) {\n reports.forEach(function (report) {\n removeLuggageCompliance(report.LocalId);\n });\n }\n }\n /**\r\n * Delete all luggage compliance reports of this flight from db and then from local storage\r\n * @param {number} flightId \r\n */\n\n\n function deleteAllLuggageComplianceReportsByFlightId(flightId) {\n return $http.post(apiUrl + '/LuggageCompliance/ResetLuggageCompliance', flightId, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return deleteReportsSuccessCallBack(res, flightId);\n })[\"catch\"](function (res) {\n return saveReportFailedCallBack(res);\n });\n }\n /**\r\n * The callback function upon successful submit\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} submitResponseObj\r\n */\n\n\n function deleteReportsSuccessCallBack(res, flightId) {\n submitResponseObj.success = res.data.success;\n\n if (res.data.success) {\n removeAllLuggageCompliance(flightId);\n submitResponseObj.message = \"Success\";\n } else {\n submitResponseObj.message = res.data.errorMessage;\n }\n\n return submitResponseObj;\n }\n /**\r\n * Remove all luggage compliance reports of this flight from storage\r\n * @param {number} flightId \r\n */\n\n\n function removeAllLuggageCompliance(flightId) {\n var allReports = getLuggageComplianceByFlightId(flightId);\n\n if (allReports) {\n allReports.forEach(function (report) {\n removeLuggageCompliance(report.LocalId);\n });\n }\n }\n /**\r\n * Sends flight's pending luggage compliance reports\r\n * @param {number} flightId The Flight identifier\r\n * @returns {promise} submitResponseObj\r\n */\n\n\n function submitLuggageCompliance(flightId) {\n var pendingReports = getLuggageComplianceByFlightId(flightId).filter(function (x) {\n return !x.isSynced;\n });\n var postData = {\n \"FlightId\": flightId,\n \"LuggageCompliance\": pendingReports\n };\n return $http.post(apiUrl + '/LuggageCompliance/Post', postData, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return saveReportSuccessCallBack(res, pendingReports, flightId);\n })[\"catch\"](function (res) {\n return saveReportFailedCallBack(res);\n });\n }\n /**\r\n * The callback function upon successful submit\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} submitResponseObj\r\n */\n\n\n function saveReportSuccessCallBack(res, pendingReports, flightId) {\n submitResponseObj.success = res.data.success;\n\n if (res.data.success) {\n updateLuggageComplianceStorage(res.data.data.LuggageComplianceReports, flightId);\n submitResponseObj.message = \"Success! Your input has been sent\";\n } else {\n submitResponseObj.message = res.data.errorMessage;\n }\n\n return submitResponseObj;\n }\n /**\r\n * The callback function upon failure on submit\r\n * @returns {object} submitResponseObj\r\n */\n\n\n function saveReportFailedCallBack(res) {\n submitResponseObj.success = false;\n submitResponseObj.message = \"Oops! Something went wrong\";\n return submitResponseObj;\n }\n /**\r\n * Shows sync result in dlgSync\r\n * @param {object} result Sync result status\r\n */\n\n\n function syncResultFormat(result) {\n var updateText;\n var upClass;\n\n if (result.ResponseSuccess == null) {\n updateText = \"No One Piece Compliance Checks were uploaded to the server. \";\n upClass = \"alert-cyan\";\n } else if (result.ResponseSuccess == true) {\n updateText = \"One Piece Compliance Checks were uploaded to the server. \";\n upClass = \"alert-cyan\";\n updateAllPendingsToSynced(result.LuggageComplianceReports);\n } else {\n updateText = \"One Piece Compliance Checks failed to be uploaded to the server. \";\n upClass = \"alert-deep-orange\";\n cleanOldPendingChecks();\n }\n\n return {\n updMessage: updateText,\n updClass: upClass\n };\n }\n /**\r\n * When sync succeed, update the pending luggage reports to synced\r\n */\n\n\n function updateAllPendingsToSynced(syncedReports) {\n var syncedReportsFromLS = getLuggageComplianceFromStorage().filter(function (x) {\n return x.isSynced;\n });\n syncedReports.forEach(function (syncedReport, index) {\n syncedReport.isSynced = true;\n syncedReport.LocalId = moment().valueOf() + index;\n syncedReportsFromLS.push(syncedReport);\n });\n setAllLuggageComplianceToStorage(syncedReportsFromLS);\n }\n /**\r\n * When sync fails, check for 2 day old checks and delete them\r\n */\n\n\n function cleanOldPendingChecks() {\n var unsyncedReports = getLuggageComplianceFromStorage().filter(function (x) {\n return !x.isSynced;\n });\n var today = new Date();\n var trimmedToday = new Date(today);\n unsyncedReports.forEach(function (unsyncedReport) {\n var createdDay = new Date(unsyncedReport.Created);\n var trimmedDay = new Date(createdDay);\n var diffDays = Date.DifferenceInDays(trimmedToday.trimTime(), trimmedDay.trimTime());\n\n if (diffDays >= 2) {\n removeLuggageCompliance(unsyncedReport.LocalId);\n }\n });\n }\n\n function updateLuggageComplianceStorage(LuggageComplianceReports, flightId) {\n var allLuggageReports = getLuggageComplianceFromStorage();\n var luggageReports = allLuggageReports.filter(function (x) {\n return x.FlightId != flightId;\n });\n LuggageComplianceReports.forEach(function (syncedReport, index) {\n syncedReport.isSynced = true;\n syncedReport.LocalId = moment().valueOf() + index;\n luggageReports.push(syncedReport);\n });\n setAllLuggageComplianceToStorage(luggageReports);\n }\n /**\r\n * Clean ls from old luggage reports\r\n * @param {array} flights Synced flights\r\n */\n\n\n function cleanOldData(responseFlightIds) {\n var allLuggageReports = getLuggageComplianceFromStorage(); //Filter out Philoxenia Questions of old flights\n\n allLuggageReports = allLuggageReports.filter(function (x) {\n return x != null && responseFlightIds.includes(x.FlightId);\n });\n setAllLuggageComplianceToStorage(allLuggageReports);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('twoLuggageEvents', twoLuggageEvents);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name twoLuggageEvents\r\n * @restrict E\r\n * @description\r\n * Implementation of twoLuggageEvents\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function twoLuggageEvents(LuggageComplianceFactory, PaxInfoFactory, $timeout) {\n function link(scope) {\n scope.submit = submit;\n scope.reset = resetConfirm;\n scope.resetSynced = resetSyncedConfirm;\n scope.allPassengersAreComplianceConfirmation = allPassengersAreComplianceConfirmation;\n getLuggageCompliancePassengers();\n\n function getLuggageCompliancePassengers() {\n scope.hasSyncedPassengers = false;\n scope.Passengers = [];\n scope.pendingReports = [];\n var flightId = scope.flight.FlightId;\n scope.flightCompliant = LuggageComplianceFactory.getFlightCompliantStatus(flightId); //Get cabin luggage compliance reports for this flight\n\n var luggageComplianceReports = LuggageComplianceFactory.getLuggageComplianceByFlightId(flightId); //Get pax info\n\n PaxInfoFactory.getPaxInfoFromStorage(flightId, function (paxinfo) {\n if (paxinfo) {\n luggageComplianceReports.forEach(function (luggageReport) {\n var columns = [];\n paxinfo.Seatmap.forEach(function (row) {\n row.Columns.forEach(function (column) {\n columns.push(column);\n });\n });\n var pax = columns.find(function (p) {\n return p.UCI == luggageReport.UCI;\n });\n\n if (pax) {\n //Passenger already exists - Only add events\n if (scope.Passengers.map(function (p) {\n return p.UCI;\n }).includes(luggageReport.UCI)) {\n scope.Passengers.find(function (p) {\n return p.UCI == luggageReport.UCI;\n }).isSynced = luggageReport.isSynced;\n } //Add Passenger Info & Events\n else {\n var passenger = {\n UCI: luggageReport.UCI,\n isSynced: luggageReport.isSynced,\n Name: pax.Fullname,\n SeatNo: pax.SeatNo,\n HasTwoLuggage: true,\n isOpen: false\n };\n scope.Passengers.push(passenger);\n }\n\n if (scope.Passengers.some(function (x) {\n return x.isSynced;\n })) {\n scope.hasSyncedPassengers = true;\n }\n }\n });\n }\n\n scope.pendingReports = scope.Passengers.filter(function (p) {\n return !p.isSynced;\n }); //Get flightIsCompliant report\n\n var flightIsCompliantReport = luggageComplianceReports.find(function (p) {\n return !p.isSynced && p.IsFlightCompliant;\n });\n\n if (flightIsCompliantReport) {\n scope.pendingReports.push(flightIsCompliantReport);\n }\n });\n }\n /**\r\n * Opens confirmation modal when undo is requested on an approved proposal\r\n * @memberof proposal\r\n */\n\n\n function allPassengersAreComplianceConfirmation() {\n if (!scope.flightCompliant.HasPendingsReports) {\n applyAllPassengersAreCompliant();\n } else if (!scope.flightCompliant.IsFlightCompliant && scope.flightCompliant.HasPendingsReports) {\n bootbox.dialog({\n message: ' All pending reports of passengers with 2 items on board will be cleared.',\n title: \"Confirm\",\n buttons: {\n confirm: {\n label: 'Confirm',\n className: \"btn-success\",\n callback: function callback() {\n applyAllPassengersAreCompliant();\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n }\n /**\r\n * Reset all synced luggage compliance reports of this flight and refresh\r\n */\n\n\n function resetSyncedConfirm() {\n bootbox.dialog({\n message: ' Reset synced reports.',\n title: \"Confirm\",\n buttons: {\n confirm: {\n label: 'Confirm',\n className: \"btn-warning\",\n callback: function callback() {\n resetAll();\n getLuggageCompliancePassengers();\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n /**\r\n * Reset all pendings luggage compliance reports of this flight and refresh\r\n */\n\n\n function resetConfirm() {\n bootbox.dialog({\n message: ' Reset all pending reports of passengers with 2 items on board.',\n title: \"Confirm\",\n buttons: {\n confirm: {\n label: 'Confirm',\n className: \"btn-warning\",\n callback: function callback() {\n resetAllPendings();\n getLuggageCompliancePassengers();\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n /**\r\n * Create or remove pending AllPassengersAreCompliant report of this flight\r\n */\n\n\n function applyAllPassengersAreCompliant() {\n if (scope.flightCompliant.HasPendingsReports || scope.flightCompliant.Status === 'pending') {\n resetAllPendings();\n }\n\n if (!scope.flightCompliant.IsFlightCompliant) {\n applyFlightComplianceReport();\n }\n\n getLuggageCompliancePassengers();\n }\n\n function applyFlightComplianceReport() {\n var cabinLuggageReport = {\n PNR: '',\n UCI: '',\n FlightId: scope.flight.FlightId,\n FareFamily: '',\n IsFlightCompliant: true,\n Created: moment()\n };\n LuggageComplianceFactory.saveFlightIsCompliantToStorage(cabinLuggageReport);\n }\n\n function resetAllPendings() {\n LuggageComplianceFactory.removePendingsLuggageCompliance(scope.flight.FlightId);\n }\n /**\r\n * Deletes all luggage compliance reports of this flight from DB and from local storage\r\n */\n\n\n function resetAll() {\n if (scope.isOffline) {\n scope.showPanel = \"offline\";\n } else {\n scope.showPanel = \"loading\";\n LuggageComplianceFactory.deleteAllLuggageComplianceReportsByFlightId(scope.flight.FlightId).then(function (res) {\n return handleSubmitResponse(res);\n });\n }\n }\n /**\r\n * Submit pending luggage compliance reports of this flight\r\n */\n\n\n function submit() {\n var flightId = scope.flight.FlightId;\n\n if (scope.isOffline) {\n scope.showPanel = \"offline\";\n } else {\n scope.showPanel = \"loading\";\n LuggageComplianceFactory.submitLuggageCompliance(flightId).then(function (res) {\n return handleSubmitResponse(res);\n });\n }\n }\n /**\r\n * Manage API response\r\n * @param {object} res \r\n */\n\n\n function handleSubmitResponse(res) {\n getLuggageCompliancePassengers();\n\n if (res.success) {\n manageResponseMessage(\"success\", res.message);\n $timeout(function () {\n scope.showPanel = \"luggageCompliance\";\n }, 6000);\n } else {\n manageResponseMessage(\"failure\", res.message);\n }\n }\n /**\r\n * Manage message alerts\r\n * @param {string} panelToShow \r\n * @param {string} message \r\n */\n\n\n function manageResponseMessage(panelToShow, message) {\n scope.submitMessage = message;\n scope.showPanel = panelToShow;\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/LuggageCompliance/twoLuggageEvents.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('CalendarRedirectModalCtrl', CalendarRedirectModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CalendarRedirectModalCtrl\r\n * @description \r\n * Modal to redirect to Calendar after all mandatory memos are read\r\n * @ngInject\r\n */\n\n function CalendarRedirectModalCtrl($scope, $location, $uibModalInstance) {\n $scope.gotoCalendar = gotoCalendar;\n\n function gotoCalendar() {\n cancel();\n $location.path('/');\n }\n /**\r\n * Closes modal\r\n * @memberof CalendarRedirectModalCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close('cancel');\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('MandatoryModalCtrl', MandatoryModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name MandatoryModalCtrl\r\n * @description \r\n * Warning Modal about unread mandatory memos\r\n * @ngInject\r\n */\n\n function MandatoryModalCtrl($scope, mandatoryUnread, MemoFactory, $uibModal, $routeParams, $location, $uibModalInstance) {\n $scope.mandatoryUnread = mandatoryUnread;\n $scope.gotoMandatoryUnreadMemos = gotoMandatoryUnreadMemos;\n\n function gotoMandatoryUnreadMemos() {\n $location.path('/memos/unreadMandatory');\n cancel();\n }\n /**\r\n * Closes modal\r\n * @memberof ProposalInfoModalCtr\r\n */\n\n\n function cancel() {\n $uibModalInstance.close('cancel');\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('MemoFactory', MemoFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name MemoFactory\r\n * @description \r\n * Add, Update, Delete and Get Memos.\r\n * @ngInject\r\n */\n\n function MemoFactory(FlightFactory, GroundDutyFactory, IndexedDBService, PaxInfoFactory, $q) {\n /**\r\n * Initialize the Memo\r\n * @memberof MemoFactory\r\n */\n function Memo() {\n this.Id = null;\n this.expired = false;\n }\n\n var objType = 'Memos';\n var objCallback = Memo;\n var service = {\n getMemosFromStorage: getMemosFromStorage,\n setMemosToStorage: setMemosToStorage,\n clearMemosFromStorage: clearMemosFromStorage,\n getMemosForFlight: getMemosForFlight,\n getStoredMemosIds: getStoredMemosIds,\n saveOneMemoToStorage: saveOneMemoToStorage,\n addMemoToStorage: addMemoToStorage,\n deleteMemoFromStorage: deleteMemoFromStorage,\n setMemosFromServer: setMemosFromServer,\n getMemosForGroundDuty: getMemosForGroundDuty,\n getMemosForCrewRoute: getMemosForCrewRoute,\n getUnreadMemos: getUnreadMemos,\n getMandatoryUnreadMemos: getMandatoryUnreadMemos,\n getAllUnreadGroundDutyMemos: getAllUnreadGroundDutyMemos,\n markGroundDutiesUnread: markGroundDutiesUnread,\n info: info,\n getNotHiddenMemos: getNotHiddenMemos\n };\n /**\r\n * Get Memos\r\n * @memberof MemoFactory\r\n * @param {function} callback \r\n */\n\n function getMemosFromStorage(callback) {\n //return GenericService.list(objType,objCallback);\n IndexedDBService.getAll(objType).then(function (results) {\n callback(results);\n });\n }\n\n ;\n /**\r\n * Set Memos\r\n * @memberof MemoFactory\r\n * @param {array} Memos a list of memos to set to indexedDB\r\n */\n\n function setMemosToStorage(Memos) {\n IndexedDBService.addAll(objType, Memos);\n }\n\n ;\n /**\r\n * Update Memo to Storage\r\n * @memberof MemoFactory\r\n * @param {object} Memo a memo\r\n */\n\n function saveOneMemoToStorage(Memo) {\n IndexedDBService.put(objType, Memo);\n }\n\n ;\n\n function info() {\n IndexedDBService.info(objType);\n }\n /**\r\n * Add Memo to Storage\r\n * @memberof MemoFactory\r\n * @param {object} Memo a memo\r\n */\n\n\n function addMemoToStorage(Memo) {\n IndexedDBService.add(objType, Memo);\n }\n\n ;\n /**\r\n * Delete Memo from Storage\r\n * @memberof MemoFactory\r\n * @param {number} MemoId The unique Identifier of the Memo\r\n */\n\n function deleteMemoFromStorage(MemoId) {\n IndexedDBService.remove(objType, MemoId);\n }\n\n ;\n /**\r\n * Clear Memo from Storage\r\n * @memberof MemoFactory\r\n */\n\n function clearMemosFromStorage() {\n IndexedDBService.removeAll(objType);\n }\n\n ;\n\n function ValidateCountryCategory(criteria, isDepartureCategory, isArrivalCategory) {\n var isValid = false;\n\n if (criteria.Special == \"Specific\") {\n isValid = (criteria.Field == \"Intra\" && isDepartureCategory || criteria.Field == \"Extra\" && !isDepartureCategory) && (criteria.FieldOptional == \"Intra\" && isArrivalCategory || criteria.FieldOptional == \"Extra\" && !isArrivalCategory);\n } else {\n if (criteria.Field == \"Intra\") {\n isValid = isDepartureCategory && criteria.Special != \"To\" || isArrivalCategory && criteria.Special != \"From\";\n } else if (criteria.Field == \"Extra\") {\n isValid = !isDepartureCategory && criteria.Special != \"To\" || !isArrivalCategory && criteria.Special != \"From\";\n }\n }\n\n return isValid;\n }\n\n function isValid(field, departureField, arrivalField, special) {\n var isValid = false;\n var isDeparture = departureField == field;\n var isArrival = arrivalField == field;\n\n if (special == \"From\") {\n isValid = isDeparture;\n } else if (special == \"To\") {\n isValid = isArrival;\n } else {\n isValid = isArrival || isDeparture;\n }\n\n return isValid;\n }\n /**\r\n * Gets all unread memos related to a Ground Duty\r\n * @memberof MemoFactory\r\n */\n\n\n function getAllUnreadGroundDutyMemos(callback) {\n getMemosFromStorage(function (results) {\n var memosCollection = results;\n var unreadGroundDutyMemos = [];\n\n for (var i = 0; i < memosCollection.length; i++) {\n for (var j = 0; j < memosCollection[i].MemoCriteria.length; j++) {\n var item = memosCollection[i].MemoCriteria[j];\n\n if (item.QueryType == \"GroundDutyCode\" && memosCollection[i].ReadDt == null) {\n unreadGroundDutyMemos.push(memosCollection[i]);\n break;\n }\n }\n }\n\n callback(unreadGroundDutyMemos);\n });\n }\n\n function getMemosForGroundDuty(Id, callback) {\n var groundDuty = GroundDutyFactory.getGroundDutyFromStorage(Id);\n\n if (!groundDuty) {\n return [];\n }\n\n getMemosFromStorage(function (results) {\n var memosCollection = results;\n var groundDutyMemos = [];\n var fromDutyDate = new Date(groundDuty.DutyDate).getTime();\n var toDutyDate = new Date(groundDuty.DutyDate).getTime();\n\n for (var i = 0; i < memosCollection.length; i++) {\n if (new Date(memosCollection[i].ValidFrom).getTime() <= fromDutyDate && new Date(memosCollection[i].ValidTo).getTime() >= toDutyDate) {\n for (var j = 0; j < memosCollection[i].MemoCriteria.length; j++) {\n var item = memosCollection[i].MemoCriteria[j];\n\n if (item.QueryType == \"GroundDutyCode\" && (item.Field == groundDuty.DutyNo || item.Field == groundDuty.GroundDutyNo)) {\n groundDutyMemos.push(memosCollection[i]);\n break;\n }\n }\n }\n }\n\n callback(groundDutyMemos);\n });\n }\n /**\r\n * Get Memos that are relate to this flight\r\n * @memberof MemoFactory\r\n * @param {number} Id The unique Identifier of the Memo\r\n * @param {function} callback The callback function\r\n */\n\n\n function getMemosForFlight(Id, callback) {\n var flight = FlightFactory.getFlightFromStorage(Id);\n\n if (!flight) {\n flight = FlightFactory.getLocalFlightFromStorage(Id);\n }\n\n if (!flight) {\n return [];\n }\n\n getMemosFromStorage(function (results) {\n var memosCollection = results;\n var flightMemos = [];\n PaxInfoFactory.getPaxInfoFromStorage(flight.FlightId, function (paxInfo) {\n for (var i = 0; i < memosCollection.length; i++) {\n if (new Date(memosCollection[i].ValidFrom).getTime() <= new Date(flight.ScheduledDeparture).getTime() && new Date(memosCollection[i].ValidTo).getTime() >= new Date(flight.ScheduledArrival).getTime()) {\n for (var j = 0; j < memosCollection[i].MemoCriteria.length; j++) {\n var item = memosCollection[i].MemoCriteria[j];\n\n if (item.AcRegistration == flight.AcTailNo || item.QueryType == \"Airport\" && isValid(item.Airport, flight.Departure, flight.Arrival, item.Special) || item.FlightNo == flight.FlightNo || item.AcType == flight.AcType || isValidZone(item, flight.Zones) || item.RouteStart == flight.Departure && item.RouteEnd == flight.Arrival || item.ViceVersa && item.RouteStart == flight.Arrival && item.RouteEnd == flight.Departure || item.QueryType == \"Country\" && isValid(item.Country, flight.DepartureCountry, flight.ArrivalCountry, item.Special) || item.QueryType == \"Schengen\" && ValidateCountryCategory(item, flight.DepartureSchengen, flight.ArrivalSchengen) || item.QueryType == \"European\" && ValidateCountryCategory(item, flight.DepartureEU, flight.ArrivalEU) || paxInfo && item.QueryType == \"SsrCode\" && PassengersHasSsrCode(paxInfo, item) || item.QueryType == \"TrainingId\" && item.Field == flight.TrainingIndicatorId) {\n flightMemos.push(memosCollection[i]);\n break;\n }\n }\n }\n }\n\n callback(flightMemos);\n });\n });\n }\n /**\r\n * Get Memos that are related to this crew route, by combining multiple flight and groundDuty memos \r\n * @memberof MemoFactory\r\n * @param {number} DutyNo Crew Route Identifier\r\n * @param {number} DutyDay Crew Route Day\r\n * @param {function} callback The callback function\r\n */\n\n\n function getMemosForCrewRoute(DutyNo, DutyDay, callback) {\n var groundDuties = GroundDutyFactory.getGroundDutiesByDutyNo(DutyNo, DutyDay);\n var flights = FlightFactory.getFlightsByDutyNo(DutyNo, DutyDay);\n PaxInfoFactory.getAllPaxInfoFromStorage(function (paxInfoResult) {\n getMemosFromStorage(function (results) {\n var memosCollection = results;\n var allMemos = [];\n\n for (var i = 0; i < memosCollection.length; i++) {\n var inserted = false; //first check if memo is connected with any groundDuties\n\n for (var g = 0; g < groundDuties.length; g++) {\n var fromDutyDate = new Date(groundDuties[g].DutyDate).getTime();\n var toDutyDate = new Date(groundDuties[g].DutyDate).getTime();\n\n if (new Date(memosCollection[i].ValidFrom).getTime() <= fromDutyDate && new Date(memosCollection[i].ValidTo).getTime() >= toDutyDate) {\n for (var j = 0; j < memosCollection[i].MemoCriteria.length; j++) {\n var item = memosCollection[i].MemoCriteria[j];\n\n if (item.QueryType == \"GroundDutyCode\" && (item.Field == groundDuties[g].DutyNo || item.Field == groundDuties[g].GroundDutyNo)) {\n allMemos.push(memosCollection[i]);\n inserted = true;\n break;\n }\n }\n }\n\n if (inserted) break; //don't check other groundDuties - memo is already inserted\n } //if memo was checked for all groundDuties and was not connected with any, check in flights\n\n\n if (!inserted) {\n for (var f = 0; f < flights.length; f++) {\n var paxInfo = null;\n\n if (new Date(memosCollection[i].ValidFrom).getTime() < new Date(flights[f].ScheduledDeparture).getTime() && new Date(memosCollection[i].ValidTo).getTime() > new Date(flights[f].ScheduledArrival).getTime()) {\n //check if flight has paxInfo \n for (var p = 0; p < paxInfoResult.length; p++) {\n if (paxInfoResult[p].FlightId == flights[f].FlightId) {\n paxInfo = paxInfoResult[p];\n break;\n }\n }\n\n for (var j = 0; j < memosCollection[i].MemoCriteria.length; j++) {\n var item = memosCollection[i].MemoCriteria[j];\n\n if (item.AcRegistration == flights[f].AcTailNo || item.QueryType == \"Airport\" && isValid(item.Airport, flights[f].Departure, flights[f].Arrival, item.Special) || item.FlightNo == flights[f].FlightNo || item.AcType == flights[f].AcType || isValidZone(item.Zone, flights[f].Zones) || item.RouteStart == flights[f].Departure && item.RouteEnd == flights[f].Arrival || item.ViceVersa && item.RouteStart == flights[f].Arrival && item.RouteEnd == flights[f].Departure || item.QueryType == \"Country\" && isValid(item.Country, flights[f].DepartureCountry, flights[f].ArrivalCountry, item.Special) || item.QueryType == \"Schengen\" && ValidateCountryCategory(item, flights[f].DepartureSchengen, flights[f].ArrivalSchengen) || item.QueryType == \"European\" && ValidateCountryCategory(item, flights[f].DepartureEU, flights[f].ArrivalEU) || paxInfo && item.QueryType == \"SsrCode\" && PassengersHasSsrCode(paxInfo, item) || item.QueryType == \"TrainingId\" && item.Field == flights[f].TrainingIndicatorId) {\n allMemos.push(memosCollection[i]);\n inserted = true;\n break;\n }\n }\n }\n\n if (inserted) break; //don't check other flights - memo is already inserted\n }\n }\n }\n\n callback(allMemos);\n });\n });\n }\n\n function PassengersHasSsrCode(paxInfo, memoCriterion) {\n var retVal = false;\n\n for (var key in paxInfo.PassengerSummaryY) {\n if (key === memoCriterion.Field && paxInfo.PassengerSummaryY[key] > 0) {\n retVal = true;\n break;\n }\n }\n\n for (var key in paxInfo.PassengerSummaryX) {\n if (key === memoCriterion.Field && paxInfo.PassengerSummaryY[key] > 0) {\n retVal = true;\n break;\n }\n }\n\n return retVal;\n }\n /**\r\n * Check if the zone is valid\r\n * @memberof MemoFactory\r\n * @param {CriteriaZone} Zone from MemoCriteria\r\n * @param {FlightZones} List of Zones from flight\r\n */\n\n\n function isValidZone(CriteriaZone, FlightZones) {\n if (!CriteriaZone || CriteriaZone.Type != \"Zone\" || !FlightZones || FlightZones.length == 0) {\n return false;\n } else {\n // some is equivalent to Any()\n var zoneExist = FlightZones.some(function (item) {\n return item.Title.toUpperCase() == CriteriaZone.Field.toUpperCase() && item.Class.toUpperCase() == CriteriaZone.FieldOptional.toUpperCase();\n });\n return zoneExist;\n }\n }\n /**\r\n * Get Stored Memos \r\n * @memberof MemoFactory\r\n * @param {function} callback The callback function\r\n */\n\n\n function getStoredMemosIds(callback) {\n getMemosFromStorage(function (memos) {\n var memoIds = [];\n\n for (var i = 0; i < memos.length; i++) {\n var memoIdRead = {\n Id: memos[i].Id,\n ReadDt: memos[i].ReadDt\n };\n memoIds.push(memoIdRead);\n }\n\n callback(memoIds);\n });\n }\n /**\r\n * set memos from server api \r\n * @memberof MemoFactory\r\n * @param {array} memos The memos \r\n * @param {array} memoIdsToSend The old memos of the storage\r\n * @param {string} lastSyncDate The last Sync Date \r\n */\n\n\n function setMemosFromServer(memos, memoIdsToSend, lastSyncDate) {\n if (!memoIdsToSend || memoIdsToSend.length == 0 || !lastSyncDate) {\n setMemosToStorage(memos);\n } else {\n for (var j = 0; j < memos.length; j++) {\n var IsMemoIncluded = false;\n\n for (var h = 0; h < memoIdsToSend.length; h++) {\n if (memos[j].Id == memoIdsToSend[h].Id) {\n IsMemoIncluded = true;\n break;\n }\n }\n\n if (IsMemoIncluded) {\n memos[j].IsUpdated = true;\n memos[j].IsNew = false;\n saveOneMemoToStorage(memos[j]);\n } else {\n memos[j].IsNew = true;\n memos[j].IsUpdated = false;\n addMemoToStorage(memos[j]);\n }\n }\n }\n }\n /**\r\n * Get Unread Memos \r\n * @memberof MemoFactory\r\n */\n\n\n function getUnreadMemos(callback) {\n getNotHiddenMemos(function (memos) {\n if (!memos) return [];\n var arrayLength = memos.length;\n var result = [];\n\n for (var i = 0; i < arrayLength; i++) {\n if (!memos[i].ReadDt) {\n result.push(memos[i]);\n }\n }\n\n callback(result);\n });\n }\n /**\r\n * Get Count of Unread Mandatory Memos\r\n * @memberof MemoFactory\r\n */\n\n\n function getMandatoryUnreadMemos(callback) {\n getNotHiddenMemos(function (memos) {\n if (!memos) return [];\n var result = [];\n var arrayLength = memos.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (!memos[i].ReadDt && memos[i].IsMandatory) {\n result.push(memos[i]);\n }\n }\n\n callback(result);\n });\n }\n /**\r\n * Flags Ground Duties if they have at least one unread memo\r\n * @memberof MemoFactory\r\n */\n\n\n function markGroundDutiesUnread() {\n getAllUnreadGroundDutyMemos(function (groundDutyMemos) {\n var groundDuties = GroundDutyFactory.getGroundDutiesFromStorage();\n\n if (groundDuties != null) {\n for (var i = 0; i < groundDuties.length; i++) {\n groundDuties[i].Unread = false; //check if this ground duty has any unread ground duty memo\n\n var fromDutyDate = new Date(groundDuties[i].DutyDate).getTime();\n var toDutyDate = new Date(groundDuties[i].DutyDate).getTime();\n\n for (var j = 0; j < groundDutyMemos.length; j++) {\n if (new Date(groundDutyMemos[j].ValidFrom).getTime() <= fromDutyDate && new Date(groundDutyMemos[j].ValidTo).getTime() >= toDutyDate) {\n for (var z = 0; z < groundDutyMemos[j].MemoCriteria.length; z++) {\n var item = groundDutyMemos[j].MemoCriteria[z];\n\n if (item.Field == groundDuties[i].DutyNo || item.Field == groundDuties[i].GroundDutyNo) {\n groundDuties[i].Unread = true;\n break;\n }\n }\n }\n }\n }\n\n GroundDutyFactory.setGroundDutiesToStorage(groundDuties);\n }\n });\n }\n /**\r\n * Exclude hidden memos from collection\r\n * @memberof MemoFactory\r\n */\n\n\n function getNotHiddenMemos(callback) {\n getMemosFromStorage(function (memos) {\n var result = [];\n\n if (memos) {\n result = memos.filter(function (memo) {\n return !memo.IsHidden;\n });\n }\n\n callback(result);\n });\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('MemoImagesFactory', MemoImagesFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name MemoImagesFactory\r\n * @description \r\n * Add, Update, Delete and Get Memo's Images.\r\n * @ngInject\r\n */\n\n function MemoImagesFactory(GenericService, IndexedDBService) {\n /**\r\n * Initialize the MemoImage\r\n * @memberof MemoImagesFactory\r\n */\n function MemoImage() {\n this.Id = null;\n }\n\n var objType = 'MemoImages';\n var objCallback = MemoImage;\n var service = {\n getMemoImagesFromStorage: getMemoImagesFromStorage,\n setMemoImagesToStorage: setMemoImagesToStorage,\n saveOneMemoImageToStorage: saveOneMemoImageToStorage,\n addMemoImageToStorage: addMemoImageToStorage,\n deleteMemoImageFromStorage: deleteMemoImageFromStorage,\n deleteMemoImageByMemoId: deleteMemoImageByMemoId,\n setImagesToServer: setImagesToServer,\n clearMemoImagesFromStorage: clearMemoImagesFromStorage,\n getMemoImagesByIndex: getMemoImagesByIndex,\n info: info\n };\n /**\r\n * Get Memo Images \r\n * @memberof MemoImagesFactory\r\n * @param {function} callback \r\n */\n\n function getMemoImagesFromStorage(callback) {\n //return GenericService.list(objType,objCallback);\n IndexedDBService.getAll(objType).then(function (results) {\n callback(results);\n });\n }\n\n ;\n /**\r\n * Get Memo Images by memo Id\r\n * @memberof MemoImagesFactory\r\n * @param {number} id Memo Id \r\n * @param {function} callback \r\n */\n\n function getMemoImagesByIndex(id, callback) {\n //return GenericService.list(objType,objCallback);\n IndexedDBService.getByIndex(objType, 'memoId', id).then(function (results) {\n callback(results);\n });\n }\n\n ;\n /**\r\n * Add Memo Images \r\n * @memberof MemoImagesFactory\r\n * @param {array} MemoImages List of memo images\r\n */\n\n function setMemoImagesToStorage(MemoImages) {\n //GenericService.saveAll(Memos,objType,objCallback);\n IndexedDBService.addAll(objType, MemoImages);\n }\n\n ;\n\n function info() {\n IndexedDBService.info(objType);\n }\n /**\r\n * Update Memo Images \r\n * @memberof MemoImagesFactory\r\n * @param {object} MemoImage a memo image\r\n */\n\n\n function saveOneMemoImageToStorage(MemoImage) {\n IndexedDBService.put(objType, MemoImage);\n }\n\n ;\n /**\r\n * Add Memo Image\r\n * @memberof MemoImagesFactory\r\n * @param {object} MemoImage a memo image\r\n */\n\n function addMemoImageToStorage(MemoImage) {\n IndexedDBService.add(objType, MemoImage);\n }\n\n ;\n /**\r\n * Delete Memo Image\r\n * @memberof MemoImagesFactory\r\n * @param {number} MemoImageId a memo image Id\r\n */\n\n function deleteMemoImageFromStorage(MemoImageId) {\n IndexedDBService.remove(objType, MemoImageId);\n }\n\n ;\n /**\r\n * Delete Memo Image by MemoId\r\n * @memberof MemoImagesFactory\r\n * @param {number} MemoId a memo Id\r\n */\n\n function deleteMemoImageByMemoId(MemoId) {\n IndexedDBService.removeByIndex(objType, 'memoId', MemoId);\n }\n\n ;\n /**\r\n * Set Memo Image by api call\r\n * @memberof MemoImagesFactory\r\n * @param {array} images List of memo images\r\n */\n\n function setImagesToServer(images) {\n for (var i = 0; i < images.length; i++) {\n addMemoImageToStorage(images[i]);\n }\n }\n /**\r\n * Remove Memo Images from storage\r\n * @memberof MemoImagesFactory\r\n */\n\n\n function clearMemoImagesFromStorage() {\n IndexedDBService.removeAll(objType);\n }\n\n ;\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('MemoModalCtrl', MemoModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name MemoModalCtrl\r\n * @description \r\n * Manages the Memo Modal\r\n * @ngInject\r\n */\n\n function MemoModalCtrl($scope, memo, $uibModalInstance, MemoImagesFactory, $sce) {\n $scope.memo = memo;\n $scope.cancel = cancel;\n $scope.hasCountry = false;\n $scope.hasFlightNo = false;\n $scope.hasAirport = false;\n $scope.hasRoute = false;\n $scope.hasAcType = false;\n $scope.hasZone = false;\n $scope.hasEuropean = false;\n $scope.hasSchengen = false;\n $scope.hasAcRegistration = false;\n $scope.hasSsrCode = false;\n $scope.hasTrainingIndicator = false;\n $scope.hasGroundDuties = false;\n $scope.hasNone = true;\n $scope.images = [];\n $scope.showImage = showImage;\n $scope.body = $sce.trustAsHtml(memo.Body);\n MemoImagesFactory.getMemoImagesByIndex(memo.Id, function (results) {\n $scope.images = results;\n });\n /**\r\n * Open A new Tab and show the image \r\n * @memberof MemoModalCtrl\r\n * @param {string} src Base64 endode string of Image\r\n */\n\n function showImage(src) {\n var image = new Image();\n image.src = src;\n var w = window.open(\"\");\n w.document.write(image.outerHTML);\n }\n /**\r\n * Show the criteria of the memo \r\n * @memberof MemoModalCtrl\r\n */\n\n\n (function changeFlags() {\n angular.forEach(memo.MemoCriteria, function (criteria) {\n if (criteria.Country || criteria.Type == \"Country\" && criteria.Field) {\n $scope.hasCountry = true;\n $scope.hasNone = false;\n }\n\n if (criteria.FlightNo || criteria.Type == \"FlightNo\" && criteria.Field) {\n $scope.hasFlightNo = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Airport || criteria.Type == \"Airport\" && criteria.Field) {\n $scope.hasAirport = true;\n $scope.hasNone = false;\n }\n\n if (criteria.RouteStart || criteria.Type == \"RouteStart\" && criteria.Field) {\n $scope.hasRoute = true;\n $scope.hasNone = false;\n }\n\n if (criteria.AcType || criteria.Type == \"AcType\" && criteria.Field) {\n $scope.hasAcType = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Zone || criteria.Type == \"Zone\" && criteria.Field) {\n $scope.hasZone = true;\n $scope.hasNone = false;\n }\n\n if (criteria.AcRegistration || criteria.Type == \"AcRegistration\" && criteria.Field) {\n $scope.hasAcRegistration = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Type == \"SsrCode\" && criteria.Field) {\n $scope.hasSsrCode = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Type == \"TrainingId\" && criteria.Field) {\n $scope.hasTrainingIndicator = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Type == \"European\" && criteria.Field) {\n $scope.hasEuropean = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Type == \"Schengen\" && criteria.Field) {\n $scope.hasSchengen = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Type == \"GroundDutyCode\" && criteria.Field) {\n $scope.hasGroundDuties = true;\n $scope.hasNone = false;\n }\n });\n })();\n /**\r\n * Close the modal\r\n * @memberof MemoModalCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close('close');\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('MemosCtrl', MemosCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name MemosCtrl\r\n * @description \r\n * Manages the Memos View\r\n * @ngInject\r\n */\n\n function MemosCtrl($scope, MemoFactory, $uibModal, $routeParams) {\n $scope.memosByCategory = [];\n $scope.openMemo = openMemo;\n $scope.searchText = '';\n $scope.searchMemos = searchMemos;\n $scope.state = 'memos';\n $scope.select = select;\n $scope.toggleSidePanel = toggleSidePanel;\n $scope.searchResultsCount = searchResultsCount;\n $scope.shownSideMenu = false;\n $scope.active = 1;\n $scope.showhideDescr = showhideDescr;\n $scope.toShowBody = true;\n $scope.toShowAppliesTo = true;\n $scope.hasCountry = false;\n $scope.hasFlightNo = false;\n $scope.hasAirport = false;\n $scope.hasRoute = false;\n $scope.hasAcType = false;\n $scope.hasZone = false;\n $scope.hasEuropean = false;\n $scope.hasSchengen = false;\n $scope.hasAcRegistration = false;\n $scope.hasSsrCode = false;\n $scope.hasTrainingIndicator = false;\n $scope.hasGroundDuties = false;\n $scope.hasNone = true;\n MemoFactory.getNotHiddenMemos(function (results) {\n var tommorowTimestamp = new Date().getTime() + 86400000;\n\n for (var i = 0; i < results.length; i++) {\n results[i].expired = new Date(results[i].ValidTo).getTime() < tommorowTimestamp;\n }\n\n $scope.memos = results;\n var memosByCategory = MemosByCategories(results);\n\n if ($routeParams.filter == 'unread') {\n $scope.radioModel = 'Unread';\n searchMemos($scope.searchText, 'Unread');\n } else if ($routeParams.filter == 'unreadMandatory') {\n $scope.radioModel = 'UnreadMandatory';\n searchMemos($scope.searchText, 'UnreadMandatory');\n } else {\n $scope.radioModel = 'All'; //default category on load\n\n $scope.selected = memosByCategory[0];\n $scope.memosByCategory = memosByCategory;\n searchResultsCount();\n }\n });\n\n function searchResultsCount() {\n var sum = 0;\n\n for (var i = 0; i < $scope.memosByCategory.length; i++) {\n sum += $scope.memosByCategory[i].memoList.length;\n }\n\n $scope.searchResults = sum;\n }\n\n function MemosByCategories(memoList) {\n var memos = [];\n\n for (var i = 0; i < memoList.length; i++) {\n var memo = memoList[i];\n\n if (!memos.filter(function (e) {\n return e.Category == memo.Category;\n }).length > 0) {\n memos.push({\n Category: memo.Category,\n memoList: [memo],\n filterList: [memo]\n });\n } else if (memos.filter(function (e) {\n return e.Category == memo.Category;\n }).length > 0) {\n memos.filter(function (object) {\n if (object.Category == memo.Category) {\n return object;\n }\n\n ;\n })[0].memoList.push(memo);\n memos.filter(function (object) {\n if (object.Category == memo.Category) {\n return object;\n }\n\n ;\n })[0].memoList.dynamicSort(\"LastUpdated\", false);\n }\n\n (function changeFlags() {\n angular.forEach(memoList[i].MemoCriteria, function (criteria) {\n if (criteria.Country || criteria.Type == \"Country\" && criteria.Field) {\n $scope.hasCountry = true;\n $scope.hasNone = false;\n }\n\n if (criteria.FlightNo || criteria.Type == \"FlightNo\" && criteria.Field) {\n $scope.hasFlightNo = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Airport || criteria.Type == \"Airport\" && criteria.Field) {\n $scope.hasAirport = true;\n $scope.hasNone = false;\n }\n\n if (criteria.RouteStart || criteria.Type == \"RouteStart\" && criteria.Field) {\n $scope.hasRoute = true;\n $scope.hasNone = false;\n }\n\n if (criteria.AcType || criteria.Type == \"AcType\" && criteria.Field) {\n $scope.hasAcType = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Zone || criteria.Type == \"Zone\" && criteria.Field) {\n $scope.hasZone = true;\n $scope.hasNone = false;\n }\n\n if (criteria.AcRegistration || criteria.Type == \"AcRegistration\" && criteria.Field) {\n $scope.hasAcRegistration = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Type == \"SsrCode\" && criteria.Field) {\n $scope.hasSsrCode = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Type == \"TrainingId\" && criteria.Field) {\n $scope.hasTrainingIndicator = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Type == \"European\" && criteria.Field) {\n $scope.hasEuropean = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Type == \"Schengen\" && criteria.Field) {\n $scope.hasSchengen = true;\n $scope.hasNone = false;\n }\n\n if (criteria.Type == \"GroundDutyCode\" && criteria.Field) {\n $scope.hasGroundDuties = true;\n $scope.hasNone = false;\n }\n });\n })();\n }\n\n return memos.dynamicSort(\"Category\", true);\n }\n\n function select(category) {\n selectMemoCategory(category);\n toggleSidePanel();\n }\n\n function selectMemoCategory(category) {\n var memosByCategory = $scope.memosByCategory;\n\n for (var i = 0; i < memosByCategory.length; i++) {\n if (memosByCategory[i].Category == category.Category) {\n $scope.selected = memosByCategory[i];\n break;\n }\n }\n }\n\n function showhideDescr() {\n $scope.toShowBody = !$scope.toShowBody;\n $scope.toShowAppliesTo = !$scope.toShowAppliesTo;\n }\n\n function toggleSidePanel() {\n $scope.shownSideMenu = !$scope.shownSideMenu;\n } //Pagination\n\n\n $scope.pageOptions = [{\n name: '5',\n value: '5'\n }, {\n name: '8',\n value: '8'\n }, {\n name: '15',\n value: '15'\n }, {\n name: '30',\n value: '30'\n }, {\n name: '50',\n value: '50'\n }];\n $scope.viewby = $scope.pageOptions[1].value;\n $scope.currentPage = 1;\n $scope.itemsPerPage = $scope.viewby;\n $scope.maxSize = 5; //Number of pager buttons to show\n\n $scope.setPage = setPage;\n $scope.setItemsPerPage = setItemsPerPage; //Controller functions\n\n /**\r\n * Set pagination page number\r\n * @memberof MemosCtrl\r\n * @param {number} pageNo list page number\r\n */\n\n function setPage(pageNo) {\n $scope.currentPage = pageNo;\n }\n /**\r\n * Set items per page \r\n * @memberof MemosCtrl\r\n * @param {number} num the Number of items to show per page\r\n */\n\n\n function setItemsPerPage(num) {\n $scope.itemsPerPage = num;\n $scope.currentPage = 1; //reset to first paghe\n }\n /**\r\n * View Selected Memo\r\n * @memberof MemosCtrl\r\n * @param {object} memo The selected Memo\r\n */\n\n\n function openMemo(_memo) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgMemo.html',\n controller: 'MemoModalCtrl',\n size: 'lg',\n keyboard: false,\n resolve: {\n memo: function memo() {\n return _memo;\n }\n }\n });\n modalInstance.result.then(function () {\n if (_memo.ReadDt == null) {\n _memo.ReadDt = new Date();\n MemoFactory.saveOneMemoToStorage(_memo); //check if memo is connected to a ground duty\n\n for (var i = 0; i < _memo.MemoCriteria.length; i++) {\n var item = _memo.MemoCriteria[i];\n\n if (item.QueryType == \"GroundDutyCode\") {\n MemoFactory.markGroundDutiesUnread();\n break;\n }\n }\n\n searchMemos($scope.searchText, '');\n }\n });\n }\n\n function redirectModal() {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgCalendarRedirect.html',\n controller: 'CalendarRedirectModalCtrl',\n backdrop: 'static',\n size: 'md',\n keyboard: false\n });\n }\n /**\r\n * Search the selected text In Memo Title and body\r\n * @memberof MemosCtrl\r\n * @param {string} text The desired search text\r\n */\n\n\n function searchMemos(text, filter) {\n if (filter != '') {\n $scope.radioModel = filter;\n }\n\n var filteredMemos = [];\n var searchText = text.toLowerCase();\n var newList = $scope.memos;\n\n for (var i = 0; i < newList.length; i++) {\n if ($scope.radioModel == 'General') {\n if (newList[i].MemoCriteria && newList[i].MemoCriteria.length > 0) {\n continue;\n }\n } else if ($scope.radioModel == 'Unread') {\n if (newList[i].ReadDt) {\n continue;\n }\n } else if ($scope.radioModel == 'Mandatory') {\n if (!newList[i].IsMandatory) {\n continue;\n }\n } else if ($scope.radioModel == 'UnreadMandatory') {\n if (newList[i].ReadDt || !newList[i].IsMandatory) {\n continue;\n }\n } else if ($scope.radioModel == 'Monthly') {\n var diffTime = Math.abs(new Date() - moment.utc(newList[i].LastUpdated).utc().toDate());\n var diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n\n if (diffDays >= 30) {\n continue;\n }\n }\n\n var memoTitle = newList[i].Title.toLowerCase();\n\n if (memoTitle.indexOf(searchText) > -1) {\n filteredMemos.push(newList[i]);\n continue;\n }\n }\n\n var memosByCategory = MemosByCategories(filteredMemos);\n $scope.memosByCategory = memosByCategory;\n var showAllCategory = {\n Category: 'Show All',\n memoList: filteredMemos,\n filterList: filteredMemos\n };\n\n if (searchText != null && searchText != undefined && searchText.length > 0) {\n memosByCategory.push(showAllCategory);\n }\n\n searchResultsCount();\n\n if (!memosByCategory || !memosByCategory.length) {\n $scope.selected == null; //selected could be null if search didn't return any results\n\n if ($scope.radioModel == 'UnreadMandatory') {\n //all mandatory memos were read\n // $scope.radioModel = 'All';\n // searchMemos(searchText, '');\n redirectModal();\n }\n } else if ($scope.selected == null) {\n //search now returns results\n $scope.selected = memosByCategory[0];\n }\n\n if (searchText != null && searchText != undefined && searchText.length > 0) {\n $scope.selected = showAllCategory;\n }\n\n var select = false;\n\n for (var i = 0; i < memosByCategory.length; i++) {\n if ($scope.selected.Category == memosByCategory[i].Category) {\n selectMemoCategory(memosByCategory[i]);\n select = true;\n break;\n }\n }\n\n if (!select) $scope.selected = memosByCategory[0];\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('MessageCtrl', MessageCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name MessageCtrl\r\n * @description \r\n * Manages the messages View\r\n * @ngInject\r\n */\n\n function MessageCtrl($scope, MessageFactory, $filter, $sce) {\n var messages = [];\n $scope.messages = MessageFactory.getMessagesFromStorage();\n messages = $scope.messages;\n $scope.messageCount = messages.length;\n $scope.state = 'messages';\n $scope.openMessage = openMessage;\n $scope.isEnabled = false;\n $scope.setupView = setupView;\n $scope.trustAsHtml = trustAsHtml;\n /**\r\n * Trust this html style text\r\n * @memberof MessageCtrl\r\n * @param {string} body The body message\r\n */\n\n function trustAsHtml(body) {\n return $sce.trustAsHtml(body);\n }\n /**\r\n * Setup the message View\r\n * @memberof MessageCtrl\r\n * @param {boolean} isEnabled Show only unread messages\r\n */\n\n\n function setupView(isEnabled) {\n $scope.messages = $filter('messageFilter')(messages, isEnabled);\n }\n /**\r\n * View Selected message\r\n * @memberof MessageCtrl\r\n * @param {object} message The selected Message\r\n */\n\n\n function openMessage(message) {\n if (message.ReadDt == null) {\n MessageFactory.markReaden(message.Id);\n message.ReadDt = new Date();\n }\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.filter('messageFilter', messageFilter);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc filter\r\n * @name messageFilter\r\n * @description \r\n * Filters messages in order to show only the unread.\r\n * @ngInject\r\n */\n\n function messageFilter() {\n return function (input, isEnable) {\n if (isEnable) {\n var result = [];\n\n for (var i = 0; i < input.length; i++) {\n if (input[i].ReadDt == null) {\n result.push(input[i]);\n }\n }\n\n return result;\n } else {\n return input;\n }\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('MessageFactory', MessageFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name MessageFactory\r\n * @description \r\n * Add, Update, Delete and Get Messages.\r\n * @ngInject\r\n */\n\n function MessageFactory(GenericService) {\n /**\r\n * Initialize the Message\r\n * @memberof MessageFactory\r\n */\n function Message() {\n this.Id = null;\n this.Title = null;\n this.AuthorName = null;\n this.Body = null;\n this.AcType = null;\n this.AirportA = null;\n this.AirportB = null;\n this.Country = null;\n this.FlightDirection = null;\n this.FlightNo = null;\n this.ValidFrom = null;\n this.ValidTo = null;\n this.PositionCP = true;\n this.PositionFA = true;\n this.PositionFO = true;\n this.PositionSA = true;\n this.QueryType = null;\n this.ReadDt = null;\n this.Registration = null;\n this.FeedbackCause = null;\n }\n\n var objType = 'messages';\n var objCallback = Message;\n var service = {\n fromObjectList: fromObjectList,\n getMessagesFromStorage: getMessagesFromStorage,\n setMessagesToStorage: setMessagesToStorage,\n clearMessagesFromStorage: clearMessagesFromStorage,\n getCountOfUnreadMessages: getCountOfUnreadMessages,\n getMessagesFromIds: getMessagesFromIds,\n getUnreadMessages: getUnreadMessages,\n markReaden: markReaden,\n markReadAsSynched: markReadAsSynched,\n getUnsynchedReadMessages: getUnsynchedReadMessages,\n storeMessagesFromServer: storeMessagesFromServer\n };\n /**\r\n * Extend an array of Objects from the default message Object\r\n * @memberof MessageFactory\r\n * @param {Array} objList an Array Of messages\r\n * @returns {Array} messages\r\n */\n\n function fromObjectList(objList) {\n return GenericService.fromObjectList(objList, objCallback);\n }\n /**\r\n * Get messages\r\n * @memberof MessageFactory\r\n * @returns {Array} messages \r\n */\n\n\n function getMessagesFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save messages to storage\r\n * @memberof MessageFactory\r\n * @param {Array} messages A list of messages\r\n */\n\n\n function setMessagesToStorage(messages) {\n GenericService.saveAll(messages, objType, objCallback);\n }\n /**\r\n * Remove the messages of the local storage\r\n * @memberof MessageFactory\r\n */\n\n\n function clearMessagesFromStorage() {\n GenericService.removeAll(objType, objCallback);\n }\n /**\r\n * Get count of unread messages\r\n * @memberof MessageFactory\r\n * @returns {number} result \r\n */\n\n\n function getCountOfUnreadMessages() {\n var messages = getMessagesFromStorage();\n if (!messages) return 0;\n var result = 0;\n var arrayLength = messages.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (!messages[i].ReadDt) {\n result++;\n }\n }\n\n return result;\n }\n /**\r\n * Get messages from given ids\r\n * @memberof MessageFactory\r\n * @param {Ids} List of Ids\r\n * @returns {Array} selectedMessages \r\n */\n\n\n function getMessagesFromIds(Ids) {\n var messages = getMessagesFromStorage();\n var selectedMessages = [];\n\n if (Ids != undefined || Ids != null) {\n for (var i = 0; i < Ids.length; i++) {\n for (var j = 0; j < messages.length; j++) {\n if (Ids[i] == messages[j].Id) {\n selectedMessages.push(messages[j]);\n break;\n }\n }\n }\n }\n\n return selectedMessages;\n }\n /**\r\n * Get unread messages\r\n * @memberof MessageFactory\r\n * @returns {Array} filteredMessages \r\n */\n\n\n function getUnreadMessages() {\n var messages = getMessagesFromStorage();\n filteredMessages = [];\n\n for (var i = 0; i < messages.length; i++) {\n if (!messages[i].ReadDt == null) {\n filteredMessages.push(messages[i]);\n }\n }\n\n return filteredMessages;\n }\n /**\r\n * Mark the message as read and save it\r\n * @memberof MessageFactory\r\n * @param {string} messageId The message identifier\r\n */\n\n\n function markReaden(messageId) {\n // get the Message array from storage\n var messages = getMessagesFromStorage();\n if (messages == null) messages = []; // find the current Message from the array (if present)\n\n var arrayLength = messages.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (messages[i].Id == messageId) {\n messages[i].ReadDt = new Date();\n break;\n }\n }\n\n setMessagesToStorage(messages);\n }\n /**\r\n * Mark the messages as synched and save it\r\n * @memberof MessageFactory\r\n * @param {array} readMessages A list of synced messages\r\n */\n\n\n function markReadAsSynched(readMessages) {\n var messages = getMessagesFromStorage();\n\n if (readMessages && messages) {\n var id;\n\n for (var i = 0; i < readMessages.length; i++) {\n id = readMessages[i].Id;\n\n for (var x = 0; x < messages.length; x++) {\n if (messages[x].Id === id) {\n messages[x].Synched = true;\n }\n }\n }\n\n setMessagesToStorage(messages);\n }\n }\n /**\r\n * Get the messages that are unsynched and not read and save them\r\n * @memberof MessageFactory\r\n * @param {array} readMessages A list of synced messages\r\n */\n\n\n function getUnsynchedReadMessages() {\n var messages = getMessagesFromStorage();\n var data = fromObjectList(messages);\n var filtered = null;\n\n if (data && data.length > 0) {\n filtered = [];\n\n for (var i = 0; i < data.length; i++) {\n if (data[i].ReadDt && !data[i].Synched) {\n filtered.push({\n Id: data[i].Id,\n ReadDt: data[i].ReadDt\n });\n }\n }\n }\n\n return filtered;\n }\n /**\r\n * Store the messages from the sync api\r\n * @memberof MessageFactory\r\n * @param {array} readMessages A list of messages\r\n */\n\n\n function storeMessagesFromServer(messages) {\n if (messages) {\n for (var i = 0; i < messages.length; i++) {\n messages[i].AuthorName = messages[i].AuthorName.replace(\"GATEWAY\\\\\", \"\");\n messages[i].AuthorName = messages[i].AuthorName.replace(\".\", \" \"); //messages already saved as Read in the server, should not be send to the server again\n\n if (messages[i].ReadDt) messages[i].Synched = true;else messages[i].Synched = false;\n }\n }\n\n setMessagesToStorage(messages);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('MessageModalCtrl', MessageModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name MessageModalCtrl\r\n * @description \r\n * Manages the message Modal\r\n * @ngInject\r\n */\n\n function MessageModalCtrl($scope, message, $uibModalInstance, $sce) {\n $scope.message = message;\n $scope.cancel = cancel;\n $scope.messageBody = $sce.trustAsHtml(message.Body);\n /**\r\n * Close the modal\r\n * @memberof MemoModalCtrl\r\n */\n\n function cancel() {\n $uibModalInstance.close('close');\n }\n }\n})();\n\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CustomerEventFactory', CustomerEventFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CustomerEventFactory\r\n * @description \r\n * Add, Update, Delete and Get Passenger Incidents\r\n * @ngInject\r\n */\n\n function CustomerEventFactory(GenericService) {\n var objType = 'CustomerEvents';\n var objCallback = CustomerEvent;\n /**\r\n * Initialize the Passenger Incident\r\n * @memberof CustomerEventFactory\r\n */\n\n function CustomerEvent() {\n this.GetId = GetId;\n this.Synced = false;\n }\n\n var service = {\n getCustomerEventsFromStorage: getCustomerEventsFromStorage,\n setCustomerEventToStorage: setCustomerEventToStorage,\n setCustomerEventsToStorage: setCustomerEventsToStorage,\n getCustomerEventsByFlightId: getCustomerEventsByFlightId,\n groupFlightCustomerEventsByPassenger: groupFlightCustomerEventsByPassenger,\n getFlightCustomerEvents: getFlightCustomerEvents,\n updateCustomerEvent: updateCustomerEvent,\n saveCustomerEvent: saveCustomerEvent,\n removeCustomerEvent: removeCustomerEvent,\n getUnsyncedCustomerEvents: getUnsyncedCustomerEvents,\n deleteOldCustomerEvents: deleteOldCustomerEvents\n };\n\n function GetId() {\n return this.LocalId;\n }\n /**\r\n * Save all Customer Events\r\n * @param {array} objList \r\n */\n\n\n function setCustomerEventsToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Add or Update a Customer Event\r\n * @param {object} customerEvent \r\n */\n\n\n function setCustomerEventToStorage(customerEvent) {\n var flightCustomerEvents = getFlightCustomerEvents(customerEvent.FlightId, customerEvent.UCI);\n\n if (flightCustomerEvents) {\n var incident = flightCustomerEvents.find(function (x) {\n return x.LocalId == customerEvent.LocalId;\n });\n\n if (incident) {\n updateCustomerEvent(customerEvent);\n } else {\n saveCustomerEvent(customerEvent);\n }\n } else {\n saveCustomerEvent(customerEvent);\n }\n }\n /**\r\n * Get all passenger events of a flight\r\n * @param {number} flightId \r\n */\n\n\n function getCustomerEventsByFlightId(flightId) {\n var allIncidents = getCustomerEventsFromStorage();\n var flightIncidents = allIncidents.filter(function (x) {\n return x.FlightId == flightId;\n });\n return flightIncidents;\n }\n\n ;\n /**\r\n * Group all customer events of a flight by passenger\r\n * @param {number} flightId \r\n */\n\n function groupFlightCustomerEventsByPassenger(flightId) {\n var oneStopShopPassengers = [];\n var allIncidents = getCustomerEventsFromStorage();\n var flightIncidents = allIncidents.filter(function (x) {\n return x.FlightId == flightId;\n });\n\n var oneStopShopPassengerIds = _toConsumableArray(new Set(flightIncidents.map(function (x) {\n return x.UCI;\n })));\n\n oneStopShopPassengerIds.forEach(function (id) {\n var incident = flightIncidents.find(function (x) {\n return x.UCI == id;\n });\n var passenger = {\n UCI: incident.UCI,\n GivenName: incident.GivenName,\n Surname: incident.Surname,\n SeatNo: incident.SeatNo,\n OneStopShopEvents: []\n };\n flightIncidents.filter(function (x) {\n return x.UCI == id;\n }).forEach(function (incident) {\n var event = {\n ToolkitItemId: incident.ToolkitItemId,\n TreatmentId: incident.TreatmentId,\n NPS: incident.NPS,\n Synced: incident.Synced\n };\n passenger.OneStopShopEvents.push(event);\n });\n oneStopShopPassengers.push(passenger);\n });\n return oneStopShopPassengers;\n }\n\n ;\n /**\r\n * Get all customer events\r\n */\n\n function getCustomerEventsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Get events for a specific passenger in a specific flight\r\n * @param {number} flightId \r\n * @param {number} uci \r\n */\n\n\n function getFlightCustomerEvents(flightId, uci) {\n var flightIncidents = getCustomerEventsByFlightId(flightId);\n var customerEvents = flightIncidents.filter(function (x) {\n return x.UCI == uci;\n });\n return customerEvents;\n }\n /**\r\n * Update a customer event (Search by FlightId-ToolkitItemId-UCI)\r\n * @param {object} customerEvent \r\n */\n\n\n function updateCustomerEvent(customerEvent) {\n GenericService.save(customerEvent, objType, objCallback);\n }\n /**\r\n * Create a new customer event\r\n * @param {object} customerEvent \r\n */\n\n\n function saveCustomerEvent(customerEvent) {\n GenericService.add(customerEvent, objType, objCallback);\n }\n /**\r\n * Remove customer event from storage \r\n * @param {object} customerEvent \r\n */\n\n\n function removeCustomerEvent(customerEventId) {\n GenericService.remove(customerEventId, objType, objCallback);\n }\n /**\r\n * Get Customers Events that have not yet been Synced\r\n */\n\n\n function getUnsyncedCustomerEvents() {\n var unsyncedEvents = getCustomerEventsFromStorage().filter(function (x) {\n return !x.Synced;\n }); //Give each event a temporary Id\n\n var tempId = 1;\n unsyncedEvents.forEach(function (event) {\n event.TemporaryId = tempId;\n tempId++; //No Treatment Id needs to be sent as null\n\n if (event.TreatmentId == -1) {\n event.TreatmentId = null;\n }\n });\n return unsyncedEvents;\n }\n /**\r\n * Deletes Customer Events that are older than 2 days\r\n * @memberof DataCleanerFactory\r\n */\n\n\n function deleteOldCustomerEvents() {\n var customerEvents = getCustomerEventsFromStorage();\n var fromDate = new Date();\n fromDate.setDate(fromDate.getDate() - 5);\n customerEvents = customerEvents.filter(function (x) {\n return x != null && x.FlightDate >= fromDate;\n });\n setCustomerEventsToStorage(customerEvents);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CustomerEventHistoryFactory', CustomerEventHistoryFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CustomerEventHistoryFactory\r\n * @description \r\n * Add, Update, Delete and Get History Customer Events for OneStopShop\r\n * @ngInject\r\n */\n\n function CustomerEventHistoryFactory(GenericService) {\n var objType = 'HistoryEvents';\n var objCallback = HistoryEvent;\n /**\r\n * Initialize the History Event\r\n * @memberof CustomerEventHistoryFactory\r\n */\n\n function HistoryEvent() {\n this.GetId = GetId;\n }\n\n var service = {\n setHistoryEventsToStorage: setHistoryEventsToStorage,\n getHistoryEventsFromStorage: getHistoryEventsFromStorage,\n getPassengerHistory: getPassengerHistory,\n refreshPassengerHistory: refreshPassengerHistory,\n deleteOldHistoryEvents: deleteOldHistoryEvents\n };\n\n function GetId() {\n return this.FlightId;\n }\n /**\r\n * Save all History Events\r\n * @param {array} objList \r\n */\n\n\n function setHistoryEventsToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Get all History Events\r\n */\n\n\n function getHistoryEventsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Get History Events of a specific passenger\r\n * @param {objects} passenger \r\n */\n\n\n function getPassengerHistory(passenger) {\n var passengerFqtv = passenger.Fqtv ? passenger.Fqtv.Number : null;\n var passengerUci = passenger.UCI; //Filter passenger by FQTV and UCI\n\n var passengerHistoryEvents = getHistoryEventsFromStorage().filter(function (p) {\n return p.FQTVNumber && passengerFqtv && p.FQTVNumber == passengerFqtv || p.UCI == passengerUci;\n });\n return passengerHistoryEvents;\n }\n\n function refreshPassengerHistory(flightHistoryEvents) {\n var history = getHistoryEventsFromStorage();\n flightHistoryEvents.forEach(function (event) {\n var historyEvent = history.find(function (x) {\n return x.ToolkitItem.Id == event.ToolkitItem.Id && x.UCI == event.UCI && x.FlightNo == event.FlightNo && x.Departure == event.Departure && x.FlightDate == event.FlightDate;\n });\n\n if (!historyEvent) {\n GenericService.add(event, objType, objCallback);\n }\n });\n }\n /**\r\n * Deletes HistoryEvents that are older than 2 days\r\n * @memberof DataCleanerFactory\r\n */\n\n\n function deleteOldHistoryEvents() {\n var historyEvents = getHistoryEventsFromStorage();\n var fromDate = new Date();\n fromDate.setDate(fromDate.getDate() - 5);\n historyEvents = historyEvents.filter(function (x) {\n return x != null && x.FlightDate >= fromDate;\n });\n setHistoryEventsToStorage(historyEvents);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('history', history);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name history\r\n * @restrict E\r\n * @description\r\n * Implementation of history\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function history(ToolkitFactory, CustomerEventHistoryFactory) {\n function link(scope) {\n scope.history = CustomerEventHistoryFactory.getPassengerHistory(scope.passenger);\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/OneStopShop/history.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('onestopshopEvent', onestopshopEvent);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name onestopshopEvent\r\n * @restrict E\r\n * @description\r\n * Implementation of onestopshopEvent\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function onestopshopEvent() {\n function link(scope) {\n scope.ToolkitItem = scope.customerEvent.ToolkitItem;\n scope.Treatment = scope.customerEvent.Treatment;\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/OneStopShop/onestopshopEvent.tpl.html',\n scope: {\n customerEvent: \"=\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('ToolkitFactory', ToolkitFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ToolkitFactory\r\n * @description \r\n * Add, Update, Delete and Get Memos.\r\n * @ngInject\r\n */\n\n function ToolkitFactory(IndexedDBService) {\n /**\r\n * Initialize the Toolkit Item\r\n * @memberof ToolkitFactory\r\n */\n function ToolkitItem() {\n this.Id = null;\n }\n\n var objType = 'ToolkitItems';\n var objCallback = ToolkitItem;\n var service = {\n setToolkitItemsFromServer: setToolkitItemsFromServer,\n getToolkitItemsFromStorage: getToolkitItemsFromStorage,\n setToolkitItemsToStorage: setToolkitItemsToStorage,\n saveToolkitItemToStorage: saveToolkitItemToStorage,\n addToolkitItemToStorage: addToolkitItemToStorage\n };\n /**\r\n * Set ToolkitItems from server API \r\n * @memberof ToolkitFactory\r\n * @param {array} toolkitItems ToolkitItems Object\r\n */\n\n function setToolkitItemsFromServer(toolkitItems) {\n //Manually add 'No Treatment' option\n toolkitItems.forEach(function (item) {\n item.Treatments.push({\n Id: -1,\n PaxCategory: 0,\n Title: \"No Treatment\",\n Description: \"\",\n Type: \"\",\n Comments: null,\n ToolkitItemId: item.Id\n });\n });\n getToolkitItemsFromStorage(function (localToolkitItems) {\n // No Toolkit Items found - Save All Incoming\n if (!localToolkitItems || localToolkitItems.length == 0) {\n setToolkitItemsToStorage(toolkitItems);\n } else {\n for (var j = 0; j < toolkitItems.length; j++) {\n var isToolkitItemIncluded = false;\n\n for (var h = 0; h < localToolkitItems.length; h++) {\n if (toolkitItems[j].Id == localToolkitItems[h].Id) {\n isToolkitItemIncluded = true;\n break;\n }\n } //Update\n\n\n if (isToolkitItemIncluded) {\n saveToolkitItemToStorage(toolkitItems[j]);\n } //Add \n else {\n addToolkitItemToStorage(toolkitItems[j]);\n }\n }\n\n localToolkitItems.filter(function (x) {\n return !toolkitItems.some(function (z) {\n return z.Id == x.Id;\n });\n }).forEach(function (item) {\n IndexedDBService.remove(objType, item.Id);\n });\n }\n });\n }\n /**\r\n * Get Toolkit Items\r\n * @memberof ToolkitFactory\r\n * @param {*} callback \r\n */\n\n\n function getToolkitItemsFromStorage(callback) {\n IndexedDBService.getAll(objType).then(function (results) {\n callback(results);\n });\n }\n /**\r\n * Set Toolkit Items\r\n * @memberof ToolkitFactory\r\n * @param {array} ToolkitItems A list of Toolkit Items to set to indexedDB\r\n */\n\n\n function setToolkitItemsToStorage(ToolkitItems, callback, errorCallback) {\n IndexedDBService.addAll(objType, ToolkitItems).then(callback)[\"catch\"](errorCallback);\n ;\n }\n\n ;\n /**\r\n * Add Toolkit Item to Storage\r\n * @memberof ToolkitFactory\r\n * @param {object} ToolkitItem\r\n */\n\n function addToolkitItemToStorage(ToolkitItem, callback, errorCallback) {\n IndexedDBService.add(objType, ToolkitItem).then(callback)[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Update Toolkit Item in Storage\r\n * @memberof ToolkitFactory\r\n * @param {object} ToolkitItem\r\n */\n\n function saveToolkitItemToStorage(ToolkitItem, callback, errorCallback) {\n IndexedDBService.put(objType, ToolkitItem).then(callback)[\"catch\"](errorCallback);\n }\n\n ;\n return service;\n }\n})();\n\"use strict\";\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('PassengerMealsCtrl', PassengerMealsCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name PassengerMealsCtrl\r\n * @description \r\n * Manages the Meal Library View\r\n * @ngInject\r\n */\n\n function PassengerMealsCtrl($scope, PassengerMealServiceFactory) {\n $scope.state = 'mealLibrary';\n $scope.selectedService = null;\n $scope.selectedCycle = null;\n $scope.filteredMeals = [];\n $scope.isAllCyclesSelected = false;\n $scope.areAllMealsOpen = false;\n $scope.filteredServices = [];\n $scope.mealServiceSearch = '';\n $scope.selectService = selectService;\n $scope.filterByCycle = filterByCycle;\n $scope.toggleAllMeals = toggleAllMeals;\n $scope.searchMeals = searchMeals;\n $scope.toggleSidePanel = toggleSidePanel;\n $scope.filterMealServices = filterMealServices;\n PassengerMealServiceFactory.getPassengerMealServicesFromStorage(function (results) {\n $scope.passengerMeals = results;\n\n if ($scope.passengerMeals.length > 0) {\n $scope.selectService($scope.passengerMeals[0]);\n $scope.filteredServices = angular.copy($scope.passengerMeals);\n }\n }); // Select a service and reset cycles and meals\n\n function selectService(service) {\n $scope.selectedService = service; // Set the selected service\n\n $scope.isAllCyclesSelected = false; // Clear the search field when selecting a new service\n\n $scope.searchText = ''; // Check if the service has cycles and filter by the first cycle\n\n if (service.ServiceCycles && service.ServiceCycles.length > 0) {\n $scope.filterByCycle(service.ServiceCycles[0]);\n } else {\n $scope.selectedCycle = null;\n $scope.filteredMeals = [];\n }\n }\n\n ; // Filter meals by cycle when cycle radio button is selected\n\n function filterByCycle(cycle) {\n $scope.selectedCycle = cycle;\n $scope.isAllCyclesSelected = false; // Clear the search field\n\n $scope.searchText = '';\n $scope.filteredMeals = cycle.Meals.sort(function (a, b) {\n return a.MealName.localeCompare(b.MealName);\n });\n }\n\n ;\n\n function filterMealServices() {\n if ($scope.mealServiceSearch && $scope.mealServiceSearch.length >= 2) {\n $scope.filteredServices = $scope.passengerMeals.filter(function (service) {\n return service.ServiceName.toLowerCase().includes($scope.mealServiceSearch.toLowerCase());\n });\n } else {\n $scope.filteredServices = angular.copy($scope.passengerMeals);\n }\n }\n\n ; // Toggle opening/closing all meals\n\n function toggleAllMeals() {\n $scope.areAllMealsOpen = !$scope.areAllMealsOpen;\n $scope.filteredMeals.forEach(function (meal) {\n meal.isInfoVisible = $scope.areAllMealsOpen;\n });\n }\n\n ; // Search meals within the selected service or cycle\n\n function searchMeals() {\n if ($scope.searchText && $scope.searchText.length >= 2) {\n var searchTextLower = $scope.searchText.toLowerCase(); // If a specific cycle is selected, filter meals by that cycle\n\n if ($scope.selectedCycle) {\n $scope.filteredMeals = $scope.selectedCycle.Meals.map(function (meal) {\n var mealNameMatch = meal.MealName.toLowerCase().includes(searchTextLower); // Filter meal items that match search criteria\n\n var filteredMealItems = meal.MealItems.map(function (item) {\n var itemNameMatch = item.ItemName.toLowerCase().includes(searchTextLower);\n var allergenMatch = item.Allergen ? item.Allergen.toLowerCase().includes(searchTextLower) : false;\n var compositionMatch = item.Composition ? item.Composition.toLowerCase().includes(searchTextLower) : false;\n var matchFound = itemNameMatch || allergenMatch || compositionMatch;\n item.highlight = matchFound; // Highlight matched items\n\n return item;\n }).filter(function (item) {\n return item.highlight;\n }); // Return the meal if it or its items match the search\n\n if (mealNameMatch || filteredMealItems.length > 0) {\n return _objectSpread({}, meal, {\n MealItems: filteredMealItems,\n highlight: mealNameMatch\n });\n }\n\n return null;\n }).filter(function (meal) {\n return meal !== null;\n }); // If \"All Cycles\" is selected, filter meals from all cycles in the selected service\n } else if ($scope.isAllCyclesSelected) {\n $scope.filteredMeals = $scope.selectedService.ServiceCycles.flatMap(function (cycle) {\n return cycle.Meals.map(function (meal) {\n var mealNameMatch = meal.MealName.toLowerCase().includes(searchTextLower);\n var filteredMealItems = meal.MealItems.map(function (item) {\n var itemNameMatch = item.ItemName.toLowerCase().includes(searchTextLower);\n var allergenMatch = item.Allergen ? item.Allergen.toLowerCase().includes(searchTextLower) : false;\n var compositionMatch = item.Composition ? item.Composition.toLowerCase().includes(searchTextLower) : false;\n var matchFound = itemNameMatch || allergenMatch || compositionMatch;\n item.highlight = matchFound;\n return item;\n }).filter(function (item) {\n return item.highlight;\n });\n\n if (mealNameMatch || filteredMealItems.length > 0) {\n return _objectSpread({}, meal, {\n MealItems: filteredMealItems,\n highlight: mealNameMatch\n });\n }\n\n return null;\n });\n }).filter(function (meal) {\n return meal !== null;\n }).sort(function (a, b) {\n return a.MealName.localeCompare(b.MealName);\n }); // Sort meals alphabetically\n } else {\n // If no cycle is selected, reset the meals (optional behavior if needed)\n $scope.filteredMeals = [];\n }\n } else {\n // If the search text is empty, show all meals for the selected cycle or all cycles\n if ($scope.selectedCycle) {\n $scope.filteredMeals = $scope.selectedCycle.Meals;\n } else if ($scope.isAllCyclesSelected) {\n $scope.filteredMeals = $scope.selectedService.ServiceCycles.flatMap(function (cycle) {\n return cycle.Meals;\n }).sort(function (a, b) {\n return a.MealName.localeCompare(b.MealName);\n }); // Sort meals alphabetically\n } else {\n $scope.filteredMeals = [];\n }\n }\n } // Toggle visibility of meal details\n\n\n $scope.toggleVisibility = function (meal) {\n meal.isInfoVisible = !meal.isInfoVisible;\n };\n\n function toggleSidePanel() {\n $scope.shownSideMenu = !$scope.shownSideMenu;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('PassengerMealServiceFactory', PassengerMealServiceFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PassengerMealServiceFactory\r\n * @description \r\n * Add, Update, Delete and Get Passenger meals allergen info.\r\n * @ngInject\r\n */\n\n function PassengerMealServiceFactory(IndexedDBService) {\n /**\r\n * Initialize MealAllergen\r\n * @memberof PassengerMealServiceFactory\r\n */\n function PassengerMealService() {\n this.Id = null;\n }\n\n var objType = 'PassengerMealServices';\n var objCallback = PassengerMealService;\n var service = {\n setPassengerMealsServicesToStorage: setPassengerMealsServicesToStorage,\n getPassengerMealServicesFromStorage: getPassengerMealServicesFromStorage,\n getPassengerMealServiceFromStorage: getPassengerMealServiceFromStorage,\n checkAndsetPassengerMealsServicesToStorage: checkAndsetPassengerMealsServicesToStorage\n };\n /**\r\n * Get all passenger meal services\r\n * @memberof PassengerMealServiceFactory\r\n * @param {function} callback \r\n */\n\n function getPassengerMealServicesFromStorage(callback) {\n IndexedDBService.getAll(objType).then(function (results) {\n callback(results);\n });\n }\n\n ;\n\n function checkAndsetPassengerMealsServicesToStorage(callback) {\n // Check if callback is null or undefined\n if (!callback || callback.length === 0) {\n return; // Exit the function if callback is null\n }\n\n IndexedDBService.getAll(objType).then(function (results) {\n // Handle cases where results are null or undefined\n if (!results || results.length === 0) {\n setPassengerMealsServicesToStorage(callback);\n } else {\n // Filter out any undefined or null entries in the results array\n var validResults = results.filter(function (service) {\n return service && service.CreatedDate;\n }); // Check if validResults contains any valid services\n\n if (validResults.length > 0) {\n var storedLatestService = validResults.reduce(function (latest, current) {\n return new Date(latest.CreatedDate) > new Date(current.CreatedDate) ? latest : current;\n });\n var firstNewService = callback[0]; // Compare the dates\n\n var storedCreatedDate = new Date(storedLatestService.CreatedDate);\n var newCreatedDate = new Date(firstNewService.CreatedDate);\n\n if (newCreatedDate > storedCreatedDate) {\n IndexedDBService.removeAll(objType).then(function () {\n setPassengerMealsServicesToStorage(callback);\n });\n }\n } else {\n // If all entries are invalid, remove all entries from IndexedDB\n IndexedDBService.removeAll(objType).then(function () {\n setPassengerMealsServicesToStorage(callback);\n });\n }\n }\n });\n }\n\n function setPassengerMealsServicesToStorage(callback) {\n IndexedDBService.addAll(objType, callback);\n }\n\n ;\n /**\r\n * Get passenger meal service By Id\r\n * @memberof PassengerMealServiceFactory\r\n * @param {function} callback \r\n */\n\n function getPassengerMealServiceFromStorage(serviceId, callback, errorCallback) {\n IndexedDBService.getById(objType, serviceId).then(function (result) {\n callback(result);\n })[\"catch\"](errorCallback);\n }\n\n ;\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('PassengerCtrl', PassengerCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name PassengerCtrl\r\n * @description \r\n * Manages the passenger information view\r\n * @ngInject\r\n */\n\n function PassengerCtrl(passenger, flightId, report, paxInfo, LuggageComplianceFactory, CampaignFactory, $scope, $uibModalInstance, $timeout, FlightFactory, CabinReportLocalEditFactory, CabinReportLocalEditCreatorFactory, UserFactory, WifiVouchersFactory, WifiAvailabilityFactory) {\n $scope.ReportIsFinal = false;\n var flight = FlightFactory.getFlightFromStorage(flightId);\n var user = UserFactory.getUser();\n if (isInFinalState(flight)) $scope.ReportIsFinal = true;\n $scope.closeModal = closeModal;\n $scope.passenger = passenger; //ugrade passenger \n\n $scope.ugradePassenger = {\n showUpgradeInput: false,\n showUpgradeWarning: false,\n showUpgradeError: false,\n showSuccess: false,\n upgradedSeatNo: '',\n successMessage: '',\n upgradeRemarks: ''\n };\n $scope.submitUpgrade = submitUpgrade;\n $scope.saveUpgrade = saveUpgrade;\n $scope.undo = undo; //wifi scopes:\n\n var wifiAvailability = WifiAvailabilityFactory.getRegistrationsFromStorage();\n\n if (wifiAvailability) {\n $scope.supportsWifi = wifiAvailability.registrations.includes(flight.AcTailNo);\n } else {\n $scope.supportsWifi = false;\n }\n\n $scope.retrieveWifiVouchers = retrieveWifiVouchers;\n $scope.showPanel = '';\n $scope.notRetrieved = true;\n $scope.createTextVoucher = createTextVoucher;\n $scope.createStreamVoucher = createStreamVoucher; //Seat Change \n\n if (passenger.ChangedSeat) {\n $scope.passenger.IsSeatChanged = true;\n } else {\n $scope.passenger.IsSeatChanged = false;\n }\n\n $scope.changeSeatFormData = {\n changedSeatNo: '',\n seatChangeRemarks: '',\n showSeatChangeInput: false\n };\n $scope.showSeatChangeWarning = false;\n $scope.showSeatChangeError = false;\n $scope.showSeatChangeSuccess = false;\n $scope.successSeatChangeMessage = '';\n $scope.submitSeatChange = submitSeatChange;\n $scope.undoSeatChange = undoSeatChange;\n $scope.saveSeatChange = saveSeatChange;\n $scope.closeChangeWarning = closeChangeWarning;\n $scope.linkedPassengersGroup = [];\n $scope.IsOld = IsOld;\n $scope.giftStatus = CampaignFactory.giftStatusList();\n $scope.isFeedbackUpdated = false;\n $scope.submitCampaignFeedback = submitCampaignFeedback;\n $scope.hideFooter = true;\n $scope.showOneStopShop = false;\n $scope.toggleFooter = toggleFooter;\n $scope.treatmentAvailability = treatmentAvailability;\n\n function toggleFooter(hide) {\n $scope.hideFooter = hide;\n } // Cabin Luggage Report\n\n\n $scope.saEligibility = flight.LineStatus != 'na';\n $scope.flightCompliant = LuggageComplianceFactory.getFlightCompliantStatus(flightId);\n $scope.updateCabinLuggageReport = updateCabinLuggageReport;\n var luggageReport = LuggageComplianceFactory.getPassengerLuggageCompliance(flightId, $scope.passenger.UCI);\n $scope.passenger.luggageCompliance = {\n hasTwoLuggage: luggageReport != null,\n isSynced: luggageReport && luggageReport.isSynced\n };\n getlinkedPassengers();\n /**\r\n * Gets called when user hits submit. Checks input then saves it\r\n * @memberof PassengerCtrl\r\n */\n\n function submitUpgrade() {\n $scope.ugradePassenger.showUpgradeWarning = false;\n $scope.ugradePassenger.showUpgradeError = false;\n\n if (!isSeatAvailableForUpgrate()) {\n return;\n }\n\n saveUpgrade();\n }\n /**\r\n * Gets called when input is ready\r\n * @memberof PassengerCtrl\r\n */\n\n\n function saveUpgrade() {\n $scope.ugradePassenger.showUpgradeWarning = false;\n $scope.ugradePassenger.showUpgradeError = false;\n updateReport();\n }\n /**\r\n * Checks if report is finalized\r\n * @memberof PassengerCtrl\r\n */\n\n\n function isInFinalState(flight) {\n var isInFinalState = flight.LineStatus === 'na' || flight.LineStatus === 'stored' || flight.LineStatus === 'storedotheruser' || flight.LineStatus === 'stored+otheruser' || flight.LineStatus === 'synched' || flight.LineStatus === 'synchedotheruser';\n return isInFinalState;\n }\n /**\r\n * fix any input into 000A format\r\n * @memberof PassengerCtrl\r\n */\n\n\n function formatSeatInput() {\n var missingZeroes = 4 - $scope.ugradePassenger.upgradedSeatNo.length;\n\n for (var i = 0; i < missingZeroes; i++) {\n $scope.ugradePassenger.upgradedSeatNo = '0' + $scope.ugradePassenger.upgradedSeatNo;\n }\n }\n /**\r\n * Puts the new seat upgrade in the report\r\n * @memberof PassengerCtrl\r\n */\n\n\n function updateReport() {\n var upgradedPassenger = {\n PNR: $scope.passenger.PNR,\n UCI: $scope.passenger.UCI,\n OriginalSeatNo: $scope.passenger.SeatNo,\n UpgradedSeatNo: $scope.ugradePassenger.upgradedSeatNo,\n Remarks: $scope.ugradePassenger.upgradeRemarks\n };\n\n if (report) {\n report.UpgradedPassengers.push(upgradedPassenger);\n } else {\n report = CabinReportLocalEditCreatorFactory.createNewLocalReportForFlight(flightId);\n report.UpgradedPassengers.push(upgradedPassenger);\n report.Status = 'draft';\n report.saveReport();\n FlightFactory.updateFlightFromReport(report);\n }\n\n CabinReportLocalEditFactory.setCabinReportToStorage(report);\n $scope.passenger.UpgradedToSeat = upgradedPassenger;\n $scope.ugradePassenger.showSuccess = true;\n $scope.ugradePassenger.successMessage = 'Upgrade submitted successfully!';\n $timeout(function () {\n $scope.ugradePassenger.showSuccess = false;\n }, 3500);\n }\n /**\r\n * Fills up the linked Passengers list. \r\n * @memberof PassengerCtrl\r\n */\n\n\n function getlinkedPassengers() {\n if (paxInfo && passenger.UCI) {\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n if (passenger.LinkedPassengers && passenger.LinkedPassengers.includes(paxInfo.Seatmap[i].Columns[j].UCI)) {\n $scope.linkedPassengersGroup.push(paxInfo.Seatmap[i].Columns[j].SeatNo);\n }\n\n if (passenger.LinkedPassengersWithProductId && passenger.LinkedPassengersWithProductId.includes(paxInfo.Seatmap[i].Columns[j].ProductId)) {\n $scope.linkedPassengersGroup.push(paxInfo.Seatmap[i].Columns[j].SeatNo);\n }\n }\n }\n }\n }\n /**\r\n * Removes upgrade from report\r\n * @memberof PassengerCtrl\r\n */\n\n\n function undo() {\n if (report) {\n report.UpgradedPassengers = report.UpgradedPassengers.filter(function (p) {\n return p.OriginalSeatNo != passenger.SeatNo && p.UCI != passenger.UCI;\n });\n report.saveReport();\n FlightFactory.updateFlightFromReport(report);\n CabinReportLocalEditFactory.setCabinReportToStorage(report);\n }\n\n $scope.passenger.UpgradedToSeat = false;\n $scope.ugradePassenger.showSuccess = true;\n $scope.ugradePassenger.successMessage = 'Upgrade removed successfuly!';\n $timeout(function () {\n $scope.ugradePassenger.showSuccess = false;\n }, 3500);\n $scope.ugradePassenger.showUpgradeInput = false;\n }\n /**\r\n * Checks if the seat is available and fires warnings or errors\r\n * @memberof PassengerCtrl\r\n * @param {string} seat The seat number \r\n * @return {boolean} isSeatAvailableForUpgrate\r\n */\n\n\n function isSeatAvailableForUpgrate() {\n $scope.ugradePassenger.upgradedSeatNo = $scope.ugradePassenger.upgradedSeatNo.toUpperCase();\n formatSeatInput();\n\n if (paxInfo) {\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n if (paxInfo.Seatmap[i].Columns[j].SeatNo == $scope.ugradePassenger.upgradedSeatNo) {\n if (paxInfo.Seatmap[i].Columns[j].IsEmptySeat) {\n return true;\n }\n\n $scope.ugradePassenger.showUpgradeWarning = true;\n return false;\n }\n }\n }\n } //not found in seatmap\n\n\n $scope.showSeatChangeError = true;\n $scope.ugradePassenger.upgradedSeatNo = '';\n return false;\n } // Seat Change\n\n /**\r\n * Checks if the seat is available and fires warnings or errors\r\n * @memberof PassengerCtrl\r\n * @param {string} seat The seat number \r\n * @return {boolean} isSeatAvailableForChange\r\n */\n\n\n function isSeatAvailableForChange() {\n /** fix any input into 000A format */\n var missingZeroes = 4 - $scope.changeSeatFormData.changedSeatNo.length;\n\n for (var i = 0; i < missingZeroes; i++) {\n $scope.changeSeatFormData.changedSeatNo = '0' + $scope.changeSeatFormData.changedSeatNo;\n }\n\n $scope.changeSeatFormData.changedSeatNo = $scope.changeSeatFormData.changedSeatNo.toUpperCase();\n\n if (paxInfo) {\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n if (paxInfo.Seatmap[i].Columns[j].SeatNo == $scope.changeSeatFormData.changedSeatNo) {\n if (paxInfo.Seatmap[i].Columns[j].IsEmptySeat && !IsAlreadyGivenSeat($scope.changeSeatFormData.changedSeatNo)) {\n return true;\n } else {\n $scope.showSeatChangeWarning = true;\n return false;\n }\n }\n }\n }\n } //not found in seatmap\n\n\n $scope.showSeatChangeError = true;\n $timeout(function () {\n $scope.showSeatChangeError = false;\n $scope.changeSeatFormData.changedSeatNo = '';\n }, 3500);\n return false;\n }\n\n function IsAlreadyGivenSeat(newSeatNo) {\n return report.ChangedSeats.some(function (item) {\n return item.NewSeatNo == newSeatNo;\n });\n }\n /**\r\n * Gets called when user hits submit. Checks input then saves it\r\n * @memberof PassengerCtrl\r\n */\n\n\n function submitSeatChange() {\n $scope.showSeatChangeWarning = false;\n $scope.showSeatChangeError = false;\n\n if (!isSeatAvailableForChange()) {\n return;\n }\n\n saveSeatChange();\n }\n\n function closeChangeWarning() {\n $scope.changeSeatFormData.showSeatChangeInput = !$scope.changeSeatFormData.showSeatChangeInput;\n $scope.showSeatChangeWarning = false;\n $scope.showSeatChangeError = false;\n }\n /**\r\n * Gets called when input is ready\r\n * @memberof PassengerCtrl\r\n */\n\n\n function saveSeatChange() {\n $scope.showSeatChangeWarning = false;\n $scope.showSeatChangeError = false;\n updateReportForSeatChange();\n }\n /**\r\n * Puts the new seat change in the report\r\n * @memberof PassengerCtrl\r\n */\n\n\n function updateReportForSeatChange() {\n var changedSeat = {\n Name: $scope.passenger.Fullname,\n PNR: $scope.passenger.PNR,\n UCI: $scope.passenger.UCI,\n OriginalSeatNo: $scope.passenger.SeatNo,\n NewSeatNo: $scope.changeSeatFormData.changedSeatNo,\n Remarks: $scope.changeSeatFormData.seatChangeRemarks\n };\n\n if (report) {\n report.ChangedSeats.push(changedSeat);\n } else {\n report = CabinReportLocalEditCreatorFactory.createNewLocalReportForFlight(flightId);\n report.ChangedSeats.push(changedSeat);\n report.Status = 'draft';\n report.saveReport();\n FlightFactory.updateFlightFromReport(report);\n }\n\n CabinReportLocalEditFactory.setCabinReportToStorage(report);\n $scope.passenger.ChangedSeat = changedSeat;\n $scope.passenger.IsSeatChanged = true;\n $scope.showSeatChangeSuccess = true;\n $scope.successSeatChangeMessage = 'Seat change submitted successfully!';\n $timeout(function () {\n $scope.showSeatChangeSuccess = false;\n }, 3500);\n }\n /**\r\n * Removes seat change from report\r\n * @memberof PassengerCtrl\r\n */\n\n\n function undoSeatChange() {\n if (report) {\n report.ChangedSeats = report.ChangedSeats.filter(function (p) {\n return p.OriginalSeatNo != passenger.SeatNo && p.UCI != passenger.UCI;\n });\n report.saveReport();\n FlightFactory.updateFlightFromReport(report);\n CabinReportLocalEditFactory.setCabinReportToStorage(report);\n }\n\n $scope.passenger.ChangedSeat = null; // ?\n\n $scope.passenger.IsSeatChanged = false;\n $scope.showSeatChangeSuccess = true;\n $scope.successSeatChangeMessage = 'Seat change removed successfuly!';\n $scope.changeSeatFormData.showSeatChangeInput = false;\n $timeout(function () {\n $scope.showSeatChangeSuccess = false;\n }, 3500);\n }\n /**\r\n * Checks if the data are new\r\n * @memberof PassengerCtrl\r\n * @param {string} time timestamp\r\n * @return {boolean} IsOld\r\n */\n\n\n function IsOld(time) {\n IsOld = false;\n\n if (time) {\n var now = new Date();\n var timeDate = new Date(time);\n var diff = now.getTime() - timeDate.getTime();\n\n if (diff > 3600000) {\n IsOld = true;\n }\n }\n\n return IsOld;\n }\n /**\r\n * Add or remove passenger from the Cabin Luggage Compliance Report\r\n * */\n\n\n function updateCabinLuggageReport() {\n var cabinLuggageReport = {\n isChecked: $scope.passenger.luggageCompliance.hasTwoLuggage,\n PNR: $scope.passenger.PNR,\n UCI: $scope.passenger.UCI,\n FlightId: $scope.flight.FlightId,\n FareFamily: $scope.passenger.FareFamily,\n IsFlightCompliant: false,\n Created: moment()\n };\n LuggageComplianceFactory.setLuggageComplianceToStorage(cabinLuggageReport);\n }\n /**\r\n * Close the modal\r\n * @memberof PassengerCtrl\r\n */\n\n\n function closeModal() {\n $uibModalInstance.dismiss('');\n }\n /**\r\n * Close the modal\r\n * @memberof PassengerCtrl\r\n */\n\n\n function submitCampaignFeedback() {\n $scope.passenger.Campaign.assignment.Status = +$scope.passenger.Campaign.assignment.StatusStr;\n CampaignFactory.updateCampaignPassenger(+flightId, $scope.passenger.Campaign.assignment);\n $scope.isFeedbackUpdated = true;\n $timeout(function () {\n $scope.isFeedbackUpdated = false;\n }, 3500);\n }\n /**\r\n * Manages OneStopShop tab visibility\r\n * Gets called if there are OneStopShop treatments available for this passenger\r\n */\n\n\n function treatmentAvailability(counter) {\n if (user.position == \"SA\") {\n $scope.ossCounter = counter;\n $scope.showOneStopShop = true;\n }\n }\n /**\r\n * Retrieve wifi vouchers\r\n * @memberof PassengerCtrl\r\n */\n\n\n function retrieveWifiVouchers(pnr) {\n $scope.showPanel = \"loading\";\n var RequestWifiVouchers = {\n PNR: pnr,\n FlightId: $scope.flight.FlightId,\n FlightDate: passenger.STDLocal\n };\n WifiVouchersFactory.retrieveWifiVouchers(RequestWifiVouchers).then(function (res) {\n return retrieveHandleSubmitResponse(res);\n });\n }\n\n function retrieveHandleSubmitResponse(res) {\n $scope.newVoucherCode = false;\n handleSubmitResponse(res);\n }\n /**\r\n * Create wifi voucher - \"Text and surf\"\r\n * @memberof PassengerCtrl\r\n */\n\n\n function createTextVoucher() {\n $scope.showPanel = \"loading\";\n var RequestCreateVoucher = {\n PNR: passenger.PNR,\n FlightId: $scope.flight.FlightId,\n FlightNumber: $scope.flight.FlightNo,\n FullName: passenger.Fullname,\n PlanId: \"2902\",\n FlightDate: passenger.STDLocal\n };\n WifiVouchersFactory.createWifiVoucher(RequestCreateVoucher).then(function (res) {\n return createHandleSubmitResponse(res);\n });\n }\n /**\r\n * Create wifi voucher - \"Stream\"\r\n * @memberof PassengerCtrl\r\n */\n\n\n function createStreamVoucher(params) {\n $scope.showPanel = \"loading\";\n var RequestCreateVoucher = {\n PNR: passenger.PNR,\n FlightId: $scope.flight.FlightId,\n FlightNumber: $scope.flight.FlightNo,\n FullName: passenger.Fullname,\n PlanId: \"2904\",\n FlightDate: passenger.STDLocal\n };\n WifiVouchersFactory.createWifiVoucher(RequestCreateVoucher).then(function (res) {\n return createHandleSubmitResponse(res);\n });\n }\n\n function createHandleSubmitResponse(res) {\n $scope.newVoucherCode = true;\n handleSubmitResponse(res);\n }\n\n function handleSubmitResponse(res) {\n if (res.success) {\n if ($scope.newVoucherCode == false) {\n $scope.textAndSurfCodes = [];\n $scope.streamCodes = [];\n $scope.newVouchers = [];\n } else {\n $scope.newVouchers = res.data;\n }\n\n $scope.notRetrieved = false;\n manageResponseMessage(\"success\", res.message);\n $scope.wifiVouchersCodes = res.data;\n $scope.wifiVouchersCodes.forEach(function (code) {\n if (code.Type == 'Text & Surf') {\n $scope.textAndSurfCodes.push(code.VoucherCode);\n }\n });\n $scope.wifiVouchersCodes.forEach(function (code) {\n if (code.Type == 'Stream') {\n $scope.streamCodes.push(code.VoucherCode);\n }\n });\n } else {\n $scope.newVoucherCode = false;\n manageResponseMessage(\"failure\", res.message);\n }\n }\n /**\r\n * Manage message alerts\r\n * @param {string} panelToShow \r\n * @param {string} message \r\n */\n\n\n function manageResponseMessage(panelToShow, message) {\n $scope.submitMessage = message;\n $scope.showPanel = panelToShow;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('PaxCtrl', PaxCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name PaxCtrl\r\n * @description \r\n * Manages the passenger seatmap and information view\r\n * @ngInject\r\n */\n\n function PaxCtrl($scope, FlightFactory, PaxInfoFactory, CampaignFactory, CabinReportLocalEditFactory, LuggageComplianceFactory, UserFactory, $route, $routeParams, $uibModal, $location) {\n var _flightId = $routeParams.flightId;\n var flight = FlightFactory.getFlightFromStorage(_flightId);\n\n var _report = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(_flightId);\n\n $scope.state = 'pax';\n $scope.flight = flight;\n $scope.showMobileMenuFilters = false;\n $scope.filterPax = filterPax;\n $scope.viewMode = viewMode;\n $scope.filterRow = filterRow;\n $scope.filterCol = filterCol;\n $scope.howClose = '';\n $scope.IsOld = IsOld;\n $scope.openPassenger = openPassenger;\n $scope.resetFilters = resetFilters;\n $scope.isConnectedFlightClose = isConnectedFlightClose;\n $scope.TimeDifference = TimeDifference;\n $scope.applyLuggageCompliance = applyLuggageCompliance;\n $scope.IsProvisional = true;\n $scope.specialMeals = 0;\n $scope.multiSelectCount = 0;\n $scope.luggageComplianceConfirmation = luggageComplianceConfirmation;\n $scope.close = close;\n $scope.toggleFlightInfoView = toggleFlightInfoView;\n $scope.mode = \"seatMap\";\n $scope.radioModel = \"Seatmap\";\n $scope.flightCompliant = LuggageComplianceFactory.getFlightCompliantStatus(_flightId);\n $scope.searchText = {\n passengerName: ''\n };\n var user = UserFactory.getUser();\n $scope.isUserSA = user.position == 'SA' ? true : false;\n\n if (flight == null) {\n flight = FlightFactory.getLocalFlightFromStorage(_flightId);\n }\n\n $scope.saEligibility = flight.LineStatus && flight.LineStatus != 'na';\n PaxInfoFactory.setMaskPaxInfoInRoute(flight);\n var _paxInfo = null;\n PaxInfoFactory.getPaxInfoFromStorage(_flightId, function (result) {\n _paxInfo = result;\n $scope.paxInfo = _paxInfo;\n\n if (_paxInfo && _report) {\n //Set upgraded seats and changed seats from report to paxinfo\n setUpgradedSeatsFromReport(_report.UpgradedPassengers);\n\n if (_report.ChangedSeats) {\n setChangedSeatsFromReport(_report.ChangedSeats); //Get ChangedSeats Counter\n\n $scope.paxInfo.changedSeatsNo = _report.ChangedSeats.length;\n } else {\n $scope.paxInfo.changedSeatsNo = 0;\n }\n }\n\n if (flight != null) {\n if (_paxInfo) {\n var connectingPax = 0;\n\n for (var i = 0; i < _paxInfo.ConnectingFlights.length; i++) {\n connectingPax = connectingPax + _paxInfo.ConnectingFlights[i].PassengerSummaryC.Passengers + _paxInfo.ConnectingFlights[i].PassengerSummaryY.Passengers;\n }\n\n $scope.connectingPax = connectingPax;\n\n for (var i = 0; i < _paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < _paxInfo.Seatmap[i].Columns.length; j++) {\n if (_paxInfo.Seatmap[i].Columns.SpecialMeal) {\n $scope.specialMeals++;\n }\n\n if (_paxInfo.Seatmap[i].Columns.SpecialMealB) {\n $scope.specialMeals++;\n }\n\n if (_paxInfo.Seatmap[i].Columns[j].ConnectingFlightId && _paxInfo.Seatmap[i].Columns[j].ConnectingFlightId != 0) {\n for (var h = 0; h < _paxInfo.ConnectingFlights.length; h++) {\n if (_paxInfo.Seatmap[i].Columns[j].ConnectingFlightId == _paxInfo.ConnectingFlights[h].FlightId) {\n _paxInfo.Seatmap[i].Columns[j].Connection = _paxInfo.ConnectingFlights[h];\n }\n }\n }\n }\n }\n\n var listSentTimestamp = new Date(_paxInfo.LastRun).getTime();\n var DepartureTimestamp = new Date(flight.ScheduledDeparture).getTime(); //20 minutes before takeoff\n\n if (DepartureTimestamp - listSentTimestamp <= 1200000) {\n $scope.IsProvisional = false;\n }\n }\n\n var flightArrivalTime = new Date(flight.ScheduledArrival).getTime();\n $scope.flightETA = flight.ETA ? new Date(flight.ETA).getTime() : flightArrivalTime;\n attachCampaign($scope.paxInfo);\n attachLuggageCompliance();\n initializeFilters();\n initializeViewMode();\n } else {\n $location.path(\"/\");\n }\n });\n /**\r\n * Set upgraded seats from report to paxinfo\r\n * @memberof PaxCtrl\r\n */\n\n function setUpgradedSeatsFromReport(upgradedPassengers) {\n for (var k = 0; k < upgradedPassengers.length; k++) {\n for (var i = 0; i < $scope.paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < $scope.paxInfo.Seatmap[i].Columns.length; j++) {\n if ($scope.paxInfo.Seatmap[i].Columns[j].UCI == upgradedPassengers[k].UCI && $scope.paxInfo.Seatmap[i].Columns[j].PNR == upgradedPassengers[k].PNR) {\n $scope.paxInfo.Seatmap[i].Columns[j].UpgradedToSeat = upgradedPassengers[k];\n }\n }\n }\n }\n }\n /**\r\n * Set changed seats from report to paxinfo\r\n * @memberof PaxCtrl\r\n */\n\n\n function setChangedSeatsFromReport(changedSeats) {\n for (var k = 0; k < changedSeats.length; k++) {\n for (var i = 0; i < $scope.paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < $scope.paxInfo.Seatmap[i].Columns.length; j++) {\n if ($scope.paxInfo.Seatmap[i].Columns[j].UCI == changedSeats[k].UCI && $scope.paxInfo.Seatmap[i].Columns[j].PNR == changedSeats[k].PNR) {\n $scope.paxInfo.Seatmap[i].Columns[j].ChangedSeat = changedSeats[k];\n }\n }\n }\n }\n }\n /**\r\n * Toggle view from seatmap to paxlist\r\n * @memberof PaxCtrl\r\n */\n\n\n function toggleFlightInfoView(mode) {\n $scope.mode = mode;\n }\n /**\r\n * Initialize Passenger Filters\r\n * @memberof PaxCtrl\r\n */\n\n\n function initializeFilters() {\n $scope.filterPaxC = false;\n $scope.filterPaxY = false;\n $scope.filterAdults = false;\n $scope.filterChildren = false;\n $scope.filterInfants = false;\n $scope.filterUMs = false;\n $scope.filterFqtv = false;\n $scope.filterConnections = false;\n $scope.filterSpecialMeals = false;\n $scope.filterFqtvSilver = false;\n $scope.filterFqtvGold = false;\n $scope.filterWheelchair = false;\n $scope.filterAssistance = false;\n $scope.filterDeportees = false;\n $scope.filterVIP = false;\n $scope.filterDHC = false;\n $scope.filterChargeableSeats = false;\n $scope.filterEligibleForUpgrade = false;\n $scope.filterSeatChanges = false;\n $scope.filterIrregularities = false;\n $scope.filterCampaigns = false;\n $scope.multiSelect = false; // $scope.searchText = { passengerName: ''};\n }\n /**\r\n * Filter Passenger by given filter\r\n * @memberof PaxCtrl\r\n * @param {string} criteria The selected filter criteria\r\n */\n\n\n function filterPax(criteria) {\n if (criteria == \"PaxC\") {\n var val = !$scope.filterPaxC;\n initializeFilters();\n $scope.filterPaxC = val;\n } else if (criteria == \"PaxY\") {\n var val = !$scope.filterPaxY;\n initializeFilters();\n $scope.filterPaxY = val;\n } else if (criteria == \"Adults\") {\n var val = !$scope.filterAdults;\n initializeFilters();\n $scope.filterAdults = val;\n } else if (criteria == \"Children\") {\n var val = !$scope.filterChildren;\n initializeFilters();\n $scope.filterChildren = val;\n } else if (criteria == \"Infants\") {\n var val = !$scope.filterInfants;\n initializeFilters();\n $scope.filterInfants = val;\n } else if (criteria == \"Fqtv-silver\") {\n var val = !$scope.filterFqtvSilver;\n initializeFilters();\n $scope.filterFqtvSilver = val;\n } else if (criteria == \"Fqtv-gold\") {\n var val = !$scope.filterFqtvGold;\n initializeFilters();\n $scope.filterFqtvGold = val;\n } else if (criteria == \"Connections\") {\n var val = !$scope.filterConnections;\n $scope.showConnections = true;\n initializeFilters();\n $scope.filterConnections = val;\n } else if (criteria == \"UMs\") {\n var val = !$scope.filterUMs;\n initializeFilters();\n $scope.filterUMs = val;\n } else if (criteria == \"SpecialMeals\") {\n var val = !$scope.filterSpecialMeals;\n initializeFilters();\n $scope.showMeals = true;\n $scope.filterSpecialMeals = val;\n } else if (criteria == \"Wheelchair\") {\n var val = !$scope.filterWheelchair;\n initializeFilters();\n $scope.filterWheelchair = val;\n } else if (criteria == \"Assistance\") {\n var val = !$scope.filterAssistance;\n initializeFilters();\n $scope.filterAssistance = val;\n } else if (criteria == \"Deportees\") {\n var val = !$scope.filterDeportees;\n initializeFilters();\n $scope.filterDeportees = val;\n } else if (criteria == \"VIP\") {\n var val = !$scope.filterVIP;\n initializeFilters();\n $scope.filterVIP = val;\n } else if (criteria == \"DHC\") {\n var val = !$scope.filterDHC;\n initializeFilters();\n $scope.filterDHC = val;\n } else if (criteria == \"ChargeableSeats\") {\n var val = !$scope.filterChargeableSeats;\n initializeFilters();\n $scope.filterChargeableSeats = val;\n } else if (criteria == \"UPGD\") {\n var val = !$scope.filterEligibleForUpgrade;\n initializeFilters();\n $scope.filterEligibleForUpgrade = val;\n } else if (criteria == \"SeatChange\") {\n var val = !$scope.filterSeatChanges;\n initializeFilters();\n $scope.filterSeatChanges = val;\n } else if (criteria == \"Irregularities\") {\n var val = !$scope.filterIrregularities;\n initializeFilters();\n $scope.filterIrregularities = val;\n } else if (criteria == \"Campaigns\") {\n var val = !$scope.filterCampaigns;\n initializeFilters();\n $scope.filterCampaigns = val;\n } else if (criteria == \"MultiSelect\") {\n var val = !$scope.multiSelect; //initializeFilters();\n\n initialiazeMultiSelectCounter();\n $scope.multiSelect = val;\n } else if (criteria == \"searchText\") {\n var val = $scope.searchText.passengerName;\n initializeFilters();\n }\n }\n\n function initialiazeMultiSelectCounter() {\n $scope.paxInfo.Seatmap.forEach(function (row) {\n row.Columns.forEach(function (column) {\n column.isMultiSelected = false;\n });\n });\n $scope.multiSelectCount = 0;\n }\n\n function luggageComplianceConfirmation() {\n if ($scope.multiSelectCount > 0) {\n $scope.modalInstance = $uibModal.open({\n templateUrl: 'dlgLuggageComplianceConfirmation.html',\n scope: $scope\n });\n }\n }\n\n function close() {\n $scope.modalInstance.close();\n }\n\n function applyLuggageCompliance() {\n var columns = [];\n $scope.paxInfo.Seatmap.forEach(function (row) {\n row.Columns.forEach(function (column) {\n columns.push(column);\n });\n });\n var selectedPassengers = columns.filter(function (c) {\n return c.isMultiSelected;\n });\n selectedPassengers.forEach(function (passenger, index) {\n var cabinLuggageReport = {\n PNR: passenger.PNR,\n UCI: passenger.UCI,\n FlightId: _flightId,\n FareFamily: passenger.FareFamily,\n IsFlightCompliant: false,\n Created: moment()\n };\n passenger.opcc = true; //attachLuggageCompliance\n\n LuggageComplianceFactory.saveLuggageComplianceToStorage(cabinLuggageReport, index);\n });\n $scope.modalInstance.close();\n filterPax('MultiSelect');\n }\n /**\r\n * Initialize View Mode\r\n * @memberof PaxCtrl\r\n */\n\n\n function initializeViewMode() {\n $scope.showPaxName = true;\n $scope.showDetails = true;\n $scope.showConnections = false;\n $scope.showMeals = false;\n }\n /**\r\n * Set the desired view style\r\n * @memberof PaxCtrl\r\n * @param {string} mode The view mode\r\n */\n\n\n function viewMode(mode) {\n if (mode == \"PaxName\") {\n $scope.showPaxName = !$scope.showPaxName;\n } else if (mode == \"Details\") {\n $scope.showDetails = !$scope.showDetails;\n } else if (mode == \"Connections\") {\n $scope.showConnections = !$scope.showConnections;\n } else if (mode == \"Meals\") {\n $scope.showMeals = !$scope.showMeals;\n }\n }\n /**\r\n * Show only the Rows that have a passenger that is valid with the current filters\r\n * @memberof PaxCtrl\r\n * @param {object} row The passenger row\r\n */\n\n\n function filterRow(row) {\n var isValid = false;\n\n if ($scope.filterPaxC || $scope.filterPaxY || $scope.filterAdults || $scope.filterChildren || $scope.filterInfants || $scope.filterUMs || $scope.filterFqtv || $scope.filterConnections || $scope.filterSpecialMeals || $scope.filterFqtvSilver || $scope.filterFqtvGold || $scope.filterWheelchair || $scope.filterWheelchair || $scope.filterAssistance || $scope.filterDeportees || $scope.filterDHC || $scope.filterVIP || $scope.filterChargeableSeats || $scope.filterEligibleForUpgrade || $scope.filterSeatChanges || $scope.filterIrregularities || $scope.filterCampaigns || $scope.multiSelect || $scope.searchText.passengerName.length > 1) {\n for (var i = 0; i < row.Columns.length; i++) {\n if (filterCol(row.Columns[i])) {\n isValid = true;\n }\n }\n } else {\n isValid = true;\n }\n\n return isValid;\n }\n /**\r\n * Disable the passenger seats that is not valid with the current filters\r\n * @memberof PaxCtrl\r\n * @param {object} col The passenger seat\r\n */\n\n\n function filterCol(col) {\n var IsValid = true;\n\n if ($scope.filterPaxC && col.Cabin != \"C\") {\n IsValid = false;\n } else if ($scope.filterPaxY && col.Cabin != \"Y\") {\n IsValid = false;\n } else if ($scope.filterAdults && col.Type != 'A') {\n IsValid = false;\n } else if ($scope.filterChildren && col.Type != 'C') {\n IsValid = false;\n } else if ($scope.filterInfants && col.Type != 'I' && !(col.Type == 'A' && col.InfantName)) {\n IsValid = false;\n } else if ($scope.filterFqtv && col.Fqtv == null) {\n IsValid = false;\n } else if ($scope.filterConnections && col.Connection == null) {\n IsValid = false;\n } else if ($scope.filterUMs && !(col.SSR != null && col.SSR.IsUMNR)) {\n IsValid = false;\n } else if ($scope.filterSpecialMeals && col.SpecialMeal == null && col.SpecialMealB == null) {\n IsValid = false;\n } else if ($scope.filterFqtvSilver && !(col.Fqtv != null && (col.Fqtv.TierLevel == 'BLUT' || col.Fqtv.TierLevel == 'SLVT'))) {\n IsValid = false;\n } else if ($scope.filterFqtvGold && !(col.Fqtv != null && col.Fqtv.TierLevel == 'GLDT')) {\n IsValid = false;\n } else if ($scope.filterWheelchair && !(col.SSR != null && col.SSR.IsGroupPRM)) {\n IsValid = false;\n } else if ($scope.filterAssistance && !(col.SSR != null && (col.SSR.IsDEAF || col.SSR.IsBLND || col.SSR.IsDPNA))) {\n IsValid = false;\n } else if ($scope.filterDeportees && !(col.SSR != null && (col.SSR.IsINAD || col.SSR.IsGroupDEP))) {\n IsValid = false;\n } else if ($scope.filterVIP && !col.IsVIP) {\n IsValid = false;\n } else if ($scope.filterDHC && !col.IsDHC) {\n IsValid = false;\n } else if ($scope.filterChargeableSeats && !(col.IsCHU || col.IsCHX)) {\n IsValid = false;\n } else if ($scope.filterEligibleForUpgrade && !col.IsEligibleForUpgrade) {\n IsValid = false;\n } else if ($scope.filterSeatChanges && !col.ChangedSeat) {\n IsValid = false;\n } else if ($scope.filterIrregularities && !col.UndeliveredChargeableSeat) {\n IsValid = false;\n } else if ($scope.filterCampaigns && !col.Campaign) {\n IsValid = false;\n } else if ($scope.multiSelect && (col.IsEmptySeat || col.SeatMode != 'Seat')) {\n IsValid = false;\n } else if ($scope.searchText.passengerName.length > 1 && (col.Fullname == null || !col.Fullname.toLowerCase().includes($scope.searchText.passengerName.toLowerCase()))) {\n IsValid = false;\n }\n\n return IsValid;\n }\n /**\r\n * Initialize Passenger Filters and the desired view style\r\n * @memberof PaxCtrl\r\n */\n\n\n function resetFilters() {\n initializeFilters();\n initializeViewMode();\n }\n /**\r\n * Open Passenger Modal View\r\n * @memberof PaxCtrl\r\n * @param {object} inputObject The passenger informations\r\n */\n\n\n function openPassenger(inputObject) {\n if ($scope.multiSelect && !inputObject.IsEmptySeat && (inputObject.SeatMode == 'Seat' || inputObject.SeatMode == 'Jumpseat')) {\n inputObject.isMultiSelected = !inputObject.isMultiSelected;\n var columns = [];\n $scope.paxInfo.Seatmap.forEach(function (row) {\n row.Columns.forEach(function (column) {\n columns.push(column);\n });\n });\n $scope.multiSelectCount = columns.filter(function (c) {\n return c.isMultiSelected;\n }).length;\n } else if (inputObject.IsEmptySeat == 0 && (inputObject.SeatMode == 'Seat' || inputObject.SeatMode == 'Jumpseat')) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgPassenger.html',\n controller: 'PassengerCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n scope: $scope,\n resolve: {\n passenger: function passenger() {\n return inputObject;\n },\n flightId: function flightId() {\n return _flightId;\n },\n paxInfo: function paxInfo() {\n return _paxInfo;\n },\n report: function report() {\n return _report;\n }\n }\n });\n modalInstance.result.then(function () {\n //passenger upgraded, reload pax\n $route.reload();\n }, function () {\n //$route.reload();\n attachCampaign();\n updateCampaignsCounters();\n attachLuggageCompliance();\n });\n }\n }\n /**\r\n * Checks if the data are new\r\n * @memberof PaxCtrl\r\n * @param {string} time timestamp\r\n * @return {boolean} IsOld\r\n */\n\n\n function IsOld(time) {\n IsOld = false;\n\n if (time) {\n var now = new Date();\n var timeDate = new Date(time);\n var diff = now.getTime() - timeDate.getTime();\n\n if (diff > 3600000) {\n IsOld = true;\n }\n }\n\n return IsOld;\n }\n /**\r\n * Calculates if a connecting flight is departs sort time after fligths arrival \r\n * @memberof PaxCtrl\r\n * @param {string} connection Connection STD\r\n * @return {string} cssClass\r\n */\n\n\n function isConnectedFlightClose(connection) {\n if (!connection) {\n return '';\n }\n\n var connFlightDate = new Date(connection.STD).getTime();\n if ($scope.flightETA > connFlightDate) return '';\n\n if (connFlightDate - $scope.flightETA < connection.MCT * 60000) {\n return 'bg-bisque';\n }\n\n if (connFlightDate - $scope.flightETA < (connection.MCT + 15) * 60000) {\n return 'bg-cornsilk';\n }\n\n return '';\n }\n /**\r\n * Returns the time difference\r\n * @memberof PaxCtrl\r\n * @param {string} time Connection STD\r\n * @return {string} timeDifference\r\n */\n\n\n function TimeDifference(time) {\n var timeString = '';\n var sign = '';\n var dayString = null;\n\n if (time) {\n var connFlightDate = new Date(time);\n var ms = connFlightDate.getTime() - $scope.flightETA; // this is a time in milliseconds\n\n if (ms < 0) {\n ms = -ms;\n sign = \"-\";\n }\n\n var days = Math.floor(ms / (24 * 60 * 60 * 1000));\n days = days < 0 ? days + 1 : days;\n var daysms = ms % (24 * 60 * 60 * 1000);\n var hours = Math.floor(daysms / (60 * 60 * 1000));\n var hoursms = ms % (60 * 60 * 1000);\n var minutes = Math.floor(hoursms / (60 * 1000));\n timeString = '' + sign + (hours > 0 ? (\"0\" + hours).substr(-2) + \":\" : '') + (\"0\" + minutes).substr(-2) + '\\'' + '';\n dayString = ' ' + days + 'd';\n }\n\n return timeString + (days && days != 0 ? dayString : '');\n }\n\n function attachCampaign() {\n if ($scope.paxInfo) {\n $scope.paxInfo.CampaignCounters = {\n pending: 0,\n completed: 0\n };\n $scope.paxInfo.Seatmap.forEach(function (s) {\n s.Columns.forEach(function (col) {\n if (col.UCI) {\n var campaignInfo = CampaignFactory.getPaxAssignment(+_flightId, col.PNR, col.UCI);\n\n if (campaignInfo.assignment) {\n col.Campaign = JSON.parse(JSON.stringify(campaignInfo));\n if (col.Campaign.assignment.Status == 0) $scope.paxInfo.CampaignCounters.pending += 1;\n if (col.Campaign.assignment.Status != 0) $scope.paxInfo.CampaignCounters.completed += 1;\n }\n }\n });\n });\n }\n }\n\n function attachLuggageCompliance() {\n if ($scope.paxInfo) {\n $scope.paxInfo.Seatmap.forEach(function (s) {\n s.Columns.forEach(function (col) {\n if (col.UCI) {\n var opccReport = LuggageComplianceFactory.getPassengerLuggageCompliance(_flightId, col.UCI);\n col.opcc = opccReport != null;\n }\n });\n });\n }\n }\n\n function updateCampaignsCounters() {\n $scope.paxInfo.CampaignCounters = {\n pending: 0,\n completed: 0\n };\n $scope.paxInfo.Seatmap.forEach(function (s) {\n s.Columns.forEach(function (col) {\n if (col.Campaign) {\n if (col.Campaign.assignment.Status == 0) {\n $scope.paxInfo.CampaignCounters.pending += 1;\n }\n\n if (col.Campaign.assignment.Status != 0) {\n $scope.paxInfo.CampaignCounters.completed += 1;\n }\n }\n });\n });\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('PaxInfoFactory', PaxInfoFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PaxInfoFactory\r\n * @description \r\n * Add, Update, Delete and Get Passenger information.\r\n * @ngInject\r\n */\n\n function PaxInfoFactory($filter, IndexedDBService, localStorageMD5Service, SyncLogFactory, FlightFactory, CrewRouteFactory) {\n /**\r\n * Initialize the PaxInfo\r\n * @memberof PaxInfoFactory\r\n */\n //TODO EPAP :: CLEAN\n function PaxInfo() {\n this.Id = null;\n this.STD_utc = null;\n this.STD_lcl = null;\n this.STA_utc = null;\n this.STA_lcl = null;\n this.AcType = null;\n this.Registration = null;\n this.ConfigurationC = null;\n this.ConfigurationY = null;\n this.PaxTotalC = null;\n this.PaxTotalY = null;\n this.MarketingFlightNos = null;\n this.SupplementaryInfo = null;\n this.LastRun = null;\n this.Offpoints = [];\n this.ConnFlights = [];\n this.Seatmap = [];\n this.curtainRows = [];\n this.Statistics = {};\n this.GetId = GetId;\n }\n\n var objType = 'PaxInfo';\n var objCallback = PaxInfo;\n var service = {\n setPaxInfoToStorage: setPaxInfoToStorage,\n getPaxInfoFromStorage: getPaxInfoFromStorage,\n getPaxInfoList: getPaxInfoList,\n updatePaxInfo: updatePaxInfo,\n getAllPaxInfoFromStorage: getAllPaxInfoFromStorage,\n cleanOldDataPaxInfo: cleanOldDataPaxInfo,\n setMaskPaxInfoInRoute: setMaskPaxInfoInRoute\n };\n migratePaxInfo();\n /**\r\n * Overide default get Id\r\n * @memberof PaxInfoFactory\r\n * @returns {number} Id \r\n */\n\n function GetId() {\n return this.FlightId;\n }\n /**\r\n * Set statistics and format passenger informtion of this flight\r\n * @memberof PaxInfoFactory\r\n * @param {paxInfo} paxInfo The passenger information of a flight\r\n * @returns {object} statistics\r\n */\n //TODO EPAP CHANGE NAME\n\n\n function GetStatistics(paxInfo) {\n var statistics = {};\n var syncLog = SyncLogFactory.getSyncLog();\n\n if (paxInfo && paxInfo.Seatmap) {\n paxInfo.curtainRows = [];\n var cabinType;\n paxInfo.DHC = 0;\n\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n if (paxInfo.Seatmap[i].Columns[j].Cabin == 'J') {\n paxInfo.Seatmap[i].Columns[j].Cabin = 'Y';\n }\n\n if (cabinType == null) {\n cabinType = paxInfo.Seatmap[i].Columns[j].Cabin;\n } else if (cabinType != paxInfo.Seatmap[i].Columns[j].Cabin && paxInfo.Seatmap[i - 1] && paxInfo.Seatmap[i].Columns[j].Cabin != null) {\n cabinType = paxInfo.Seatmap[i].Columns[j].Cabin;\n paxInfo.curtainRows.push(paxInfo.Seatmap[i - 1].RowNo);\n }\n }\n }\n }\n\n return statistics;\n }\n /**\r\n * Set Passenger information\r\n * @memberof PaxInfoFactory\r\n * @param {Array} paxInfos The passenger informations \r\n */\n\n\n function setPaxInfoToStorage(paxInfo, flightIds) {\n if (paxInfo) {\n // get paxInfo for the flights with draft reports from indexedDB (gets the new paxInfo if the flightId exists in sync response)\n getAllPaxInfoFromStorage(function (paxInfoResult) {\n var oldDraftPaxInfo = [];\n var paxInfoFlightIds = paxInfo.map(function (item) {\n return item.FlightId;\n });\n oldDraftPaxInfo = paxInfoResult.filter(function (item) {\n return flightIds.includes(item.FlightId) && !paxInfoFlightIds.includes(item.FlightId);\n }); // get new paxInfo\n\n IndexedDBService.removeAll(objType).then(function () {\n for (var i = 0; i < paxInfo.length; i++) {\n paxInfo[i].Statistics = GetStatistics(paxInfo[i]);\n }\n\n var newListPaxInfo = paxInfo.concat(oldDraftPaxInfo);\n IndexedDBService.addAll(objType, newListPaxInfo);\n });\n });\n }\n }\n /**\r\n * Clean Old Data\r\n * @memberof PaxInfoFactory\r\n * @param {Array} pendingFlightIds FlightIds with pending reports\r\n */\n\n\n function cleanOldDataPaxInfo(pendingFlightIds) {\n // get paxInfo for the flights with draft reports from indexedDB (gets the new paxInfo if the flightId exists in sync response)\n var now = moment();\n getAllPaxInfoFromStorage(function (paxInfoResult) {\n var oldDraftPaxInfo = paxInfoResult.filter(function (item) {\n return pendingFlightIds.includes(item.FlightId);\n }); // keep only the pax list with pending reports\n\n IndexedDBService.removeAll(objType).then(function () {\n IndexedDBService.addAll(objType, oldDraftPaxInfo);\n });\n });\n }\n /**\r\n * Get Passenger information for the selected flight\r\n * @memberof PaxInfoFactory\r\n * @param {number} flightId The flight id \r\n */\n\n\n function getPaxInfoFromStorage(flightId, callback) {\n //var intFlightId = 1226541;\n var intFlightId = +flightId;\n IndexedDBService.getById(objType, intFlightId).then(function (result) {\n callback(result);\n });\n }\n /**\r\n * Get Passenger information list for the selected flight\r\n * @memberof PaxInfoFactory\r\n * @param {number} flightId The flight id \r\n */\n\n\n function getPaxInfoList(flightId, callback) {\n var intFlightId = +flightId;\n var passengerList = [];\n IndexedDBService.getById(objType, intFlightId).then(function (paxInfo) {\n if (paxInfo) {\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n var passenger = paxInfo.Seatmap[i].Columns[j];\n\n if (!passenger.IsEmptySeat && passenger.SeatMode == \"Seat\") {\n passengerList.push(passenger);\n }\n }\n }\n }\n\n callback(passengerList);\n });\n }\n /**\r\n * Get Passenger information for the selected flights\r\n * @memberof PaxInfoFactory\r\n */\n\n\n function getAllPaxInfoFromStorage(callback) {\n IndexedDBService.getAll(objType).then(function (paxinfo) {\n callback(paxinfo);\n });\n }\n /**\r\n * Update Passenger information\r\n * @memberof PaxInfoFactory\r\n * @param {object} paxInfo The passenger informations \r\n */\n\n\n function updatePaxInfo(paxInfo) {\n if (paxInfo) {\n paxInfo.Statistics = GetStatistics(paxInfo);\n IndexedDBService.put(objType, paxInfo);\n }\n }\n /**\r\n * Update Passenger information\r\n * @memberof PaxInfoFactory\r\n */\n\n\n function migratePaxInfo() {\n var lsPaxInfo = localStorageMD5Service.get(objType);\n\n if (lsPaxInfo && lsPaxInfo.length > 0) {\n IndexedDBService.addAll(objType, lsPaxInfo);\n localStorageMD5Service.remove(objType);\n }\n }\n /**\r\n * Hide pax name with condition\r\n * @memberof PaxInfoFactory\r\n */\n\n\n function setMaskPaxInfoInRoute(flightInfo) {\n if (flightInfo && flightInfo.showPaxNames) {\n var applyMask = false;\n var flights = CrewRouteFactory.getCrewRouteFlights(flightInfo.DutyNo, flightInfo.DutyDay, flightInfo.FlightDate);\n flights = $filter('orderBy')(flights, 'ScheduledDeparture');\n var lastFlight = flights[flights.length - 1];\n\n if (moment.utc().diff(moment(lastFlight.ATA), 'hours') > 2) {\n //set mask\n applyMask = true;\n } else if (moment.utc().diff(moment(lastFlight.ScheduledArrival), 'hours') > 4) {\n //set mask\n applyMask = true;\n }\n\n if (applyMask) {\n flights.forEach(function (flight) {\n flight.showPaxNames = false;\n FlightFactory.updateFlight(flight);\n });\n var flightIds = flights.map(function (item) {\n return item.FlightId; // or Id (todo: check)\n });\n setMaskPaxInfoToStorage(flightIds);\n }\n }\n }\n\n function setMaskPaxInfoToStorage(flightIds) {\n getAllPaxInfoFromStorage(function (paxInfoResult) {\n var maskedPaxFlightList = [];\n maskedPaxFlightList = paxInfoResult.filter(function (item) {\n return flightIds.includes(item.FlightId);\n });\n\n for (var i = 0; i < maskedPaxFlightList.length; i++) {\n maskPaxNames(maskedPaxFlightList[i]);\n }\n\n var otherPaxInfo = paxInfoResult.filter(function (item) {\n return !flightIds.includes(item.FlightId);\n }); // get new paxInfo\n\n IndexedDBService.removeAll(objType).then(function () {\n var newListPaxInfo = otherPaxInfo.concat(maskedPaxFlightList);\n IndexedDBService.addAll(objType, newListPaxInfo);\n });\n });\n }\n\n function maskPaxNames(pax) {\n if (pax) {\n for (var i = 0; i < pax.Seatmap.length; i++) {\n for (var j = 0; j < pax.Seatmap[i].Columns.length; j++) {\n var passenger = pax.Seatmap[i].Columns[j];\n\n if (!passenger.IsEmptySeat && passenger.SeatMode == \"Seat\") {\n passenger.InfantName = passenger.InfantSurname ? \"*****\" : passenger.InfantSurname;\n passenger.InfantGivenName = passenger.InfantGivenName ? \"*****\" : passenger.InfantGivenName;\n passenger.Fullname = passenger.Fullname ? \"***** *****\" : passenger.Fullname;\n passenger.Surname = passenger.Surname ? \"*****\" : passenger.Surname;\n passenger.GivenName = passenger.GivenName ? \"*****\" : passenger.GivenName;\n }\n }\n }\n }\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('toolkit', toolkit);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name toolkit\r\n * @restrict E\r\n * @description\r\n * Implementation of toolkit\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function toolkit($timeout, ToolkitFactory, CustomerEventFactory) {\n function link(scope) {\n scope.closeAlert = closeAlert;\n scope.goBack = goBack;\n scope.removeCustomerEvent = removeCustomerEvent;\n scope.addEditIncident = addEditIncident;\n scope.isRedeemed = false;\n scope.getIsRedeemed = getIsRedeemed;\n scope.submitCustomerEvent = submitCustomerEvent;\n scope.toggleDeleteAlert = toggleDeleteAlert;\n scope.validForm = validForm;\n scope.emailFormat = /^[a-zA-Z]+[a-zA-Z0-9._]+@[a-zA-Z]+\\.[a-zA-Z.]{2,5}$/;\n scope.mobileFormat = /^[\\+]?[(]?[0-9]{3}[)]?[-\\s\\.]?[0-9]{3}[-\\s\\.]?[0-9]{4,6}$/im;\n scope.FQTVNumber = scope.passenger.Fqtv && scope.passenger.Fqtv.Carrier == \"A3\" ? scope.passenger.Fqtv.Number : null;\n setupToolkit();\n\n function setupToolkit() {\n initializeToolkit(scope.passenger, function (toolKitItems) {\n scope.toolkit = toolKitItems;\n scope.customerEvents = getCustomerEvents(toolKitItems, scope.flight.FlightId, scope.passenger.UCI);\n\n if (scope.toolkit.some(function (x) {\n return x.Treatments.length;\n })) {\n scope.treatmentAvailability({\n counter: scope.customerEvents.length\n });\n }\n\n if (scope.customerEvents.length > 0) {\n scope.isListView = true;\n scope.isEdit = false;\n } else {\n addEditIncident();\n }\n });\n }\n /**\r\n * Save Customer Event in local storage\r\n */\n\n\n function submitCustomerEvent() {\n var customerEvent = {\n ToolkitItemId: scope.newForm.selectedIncident.Id,\n TreatmentId: scope.newForm.selectedTreatment,\n PNR: scope.passenger.PNR,\n UCI: scope.passenger.UCI,\n FQTVNumber: scope.FQTVNumber,\n FQTVTierLevel: scope.passenger.Fqtv && scope.passenger.Fqtv.Carrier == \"A3\" ? scope.passenger.Fqtv.TierLevel : null,\n NPS: scope.newForm.NPS,\n Comments: scope.newForm.CrewComments,\n FlightId: scope.flight.FlightId,\n FlightNo: scope.flight.FlightNo,\n Departure: scope.flight.Departure,\n Arrival: scope.flight.Arrival,\n FlightDate: scope.flight.FlightDate,\n Email: scope.newForm.passengerEmail,\n TelephoneCode: scope.newForm.telephoneCode,\n Mobile: scope.newForm.passengerMobile,\n ContactLanguage: scope.newForm.contactLanguage,\n GivenName: scope.passenger.GivenName,\n Surname: scope.passenger.Surname,\n SeatNo: scope.passenger.SeatNo,\n ClassOfService: scope.passenger.Cabin,\n LocalId: scope.newForm.LocalId ? scope.newForm.LocalId : moment().valueOf()\n };\n CustomerEventFactory.setCustomerEventToStorage(customerEvent);\n goBack();\n scope.isIncidentUpdated = true;\n $timeout(function () {\n scope.isIncidentUpdated = false;\n }, 5000);\n }\n /**\r\n * Add or update a customer event\r\n * @param {object} customerEvent Selected customer event from list (edit mode)\r\n */\n\n\n function addEditIncident(customerEvent) {\n scope.toolkitOptions = scope.toolkit.filter(function (x) {\n return !scope.customerEvents.some(function (y) {\n return y.Id == x.Id;\n }) && !x.Fallback;\n }).concat(scope.toolkit.filter(function (x) {\n return x.Fallback;\n }));\n scope.newForm = {\n selectedIncident: null,\n selectedTreatment: null,\n passengerEmail: null,\n contactLanguage: \"EN\",\n telephoneCode: \"30\",\n //Defaut value GR\n passengerMobile: null,\n NPS: null,\n CrewComments: null\n };\n scope.isEdit = customerEvent == null || customerEvent == undefined;\n\n if (customerEvent) {\n scope.newForm = {\n selectedIncident: customerEvent,\n selectedTreatment: customerEvent.CustomerEvent.TreatmentId,\n passengerEmail: customerEvent.CustomerEvent.Email,\n telephoneCode: customerEvent.CustomerEvent.TelephoneCode,\n passengerMobile: customerEvent.CustomerEvent.Mobile,\n contactLanguage: customerEvent.CustomerEvent.ContactLanguage,\n NPS: customerEvent.CustomerEvent.NPS,\n CrewComments: customerEvent.CustomerEvent.Comments,\n LocalId: customerEvent.CustomerEvent.LocalId\n };\n\n if (!scope.toolkitOptions.some(function (x) {\n return x.Id == customerEvent.Id;\n })) {\n scope.toolkitOptions.push(scope.toolkit.find(function (x) {\n return x.Id == customerEvent.Id;\n }));\n }\n }\n\n scope.isListView = false; //Change view\n }\n /**\r\n * Gets treatment redeem\r\n */\n\n\n function getIsRedeemed(item) {\n scope.isRedeem = scope.toolkitOptions.flatMap(function (x) {\n return x.Treatments;\n }).filter(function (s) {\n return s.Id == item;\n }).map(function (f) {\n return f.IsRedeemed;\n })[0];\n }\n /**\r\n * Go to Toolkit Items list view\r\n */\n\n\n function goBack() {\n scope.isIncidentUpdated = false;\n scope.deleteAlert = false;\n scope.isListView = true;\n scope.isEdit = false;\n scope.newForm = null;\n setupToolkit();\n }\n /**\r\n * Validate form before saving\r\n */\n\n\n function validForm() {\n // 1. Has a treatment selected\n // 2. Has NPS Score selected\n // 3. Has passenger email when nqtvNo is null or ( email or mobile is not null) \n var validForm = false;\n var form = scope.newForm;\n\n if (form) {\n validForm = form.selectedIncident && form.selectedTreatment && form.NPS && (scope.FQTVNumber && (form.passengerEmail || form.passengerMobile) || !scope.FQTVNumber && form.passengerEmail);\n }\n\n return validForm;\n }\n /**\r\n * Remove Customer Event from local storage\r\n */\n\n\n function removeCustomerEvent() {\n CustomerEventFactory.removeCustomerEvent(scope.newForm.LocalId);\n scope.treatmentAvailability({\n counter: scope.customerEvents.length\n });\n goBack();\n }\n /**\r\n * Close successful save alert\r\n */\n\n\n function closeAlert() {\n scope.isIncidentUpdated = false;\n }\n\n function toggleDeleteAlert() {\n scope.deleteAlert = !scope.deleteAlert;\n }\n }\n\n var passengerCategories = {\n none: 0,\n gold: 1,\n business: 2,\n silver: 3,\n blue: 4,\n economy: 5\n };\n /**\r\n * Gets all toolkit items and filter treatments depending on passenger's class\r\n * @param {object} passenger \r\n * @param {function} callback \r\n */\n\n function initializeToolkit(passenger, callback) {\n ToolkitFactory.getToolkitItemsFromStorage(function (toolKitItems) {\n var paxCategories = getPaxCategories(passenger);\n toolKitItems.forEach(function (item) {\n var matchingCategories = paxCategories.some(function (category) {\n return item.TouchpointCategories.includes(category);\n });\n var treatmentGroups = item.Treatments.groupByKey(\"PaxCategory\");\n\n if (matchingCategories && paxCategories.contains(passengerCategories.gold) && treatmentGroups[passengerCategories.gold]) {\n item.Treatments = treatmentGroups[passengerCategories.gold];\n } else if (matchingCategories && paxCategories.contains(passengerCategories.business) && treatmentGroups[passengerCategories.business]) {\n item.Treatments = treatmentGroups[passengerCategories.business];\n } else if (matchingCategories && paxCategories.contains(passengerCategories.silver) && treatmentGroups[passengerCategories.silver]) {\n item.Treatments = treatmentGroups[passengerCategories.silver];\n } else if (matchingCategories && paxCategories.contains(passengerCategories.blue) && treatmentGroups[passengerCategories.blue]) {\n item.Treatments = treatmentGroups[passengerCategories.blue];\n } else if (matchingCategories && paxCategories.contains(passengerCategories.economy) && treatmentGroups[passengerCategories.economy]) {\n item.Treatments = treatmentGroups[passengerCategories.economy];\n } else {\n //No available treatments for this passenger\n item.Treatments = [];\n }\n\n if (item.Treatments.length) {\n //Add 'No Treatment'\n item.Treatments = item.Treatments.concat(treatmentGroups[passengerCategories.none]);\n }\n }); //Toolkit Items without treatments should not be visible\n\n toolKitItems = toolKitItems.filter(function (t) {\n return t.Treatments && t.Treatments.length;\n });\n callback(toolKitItems);\n });\n }\n\n function getPaxCategories(passenger) {\n var passengerClass = passenger.Cabin;\n var passengerFqtv = passenger.Fqtv && passenger.Fqtv.Carrier == \"A3\" ? passenger.Fqtv.TierDescription.toLowerCase() : null;\n var paxCategories = [];\n\n if (passengerClass == 'C') {\n paxCategories.push(passengerCategories.business);\n }\n\n if (passengerFqtv == 'gold') {\n paxCategories.push(passengerCategories.gold);\n } else if (passengerFqtv == 'silver') {\n paxCategories.push(passengerCategories.silver);\n } else if (passengerFqtv == 'blue') {\n paxCategories.push(passengerCategories.blue);\n } else if (passengerClass == 'Y') {\n paxCategories.push(passengerCategories.economy);\n }\n\n return paxCategories;\n }\n /**\r\n * Get customer events by flightId and UCI and attach them to their toolkitItem\r\n * @param {array} toolKitItems \r\n * @param {number} flightId \r\n * @param {number} UCI \r\n */\n\n\n function getCustomerEvents(toolKitItems, flightId, UCI) {\n var customerEvents = []; //All events created for this passenger & on this flight\n\n var storedCustomerEvents = CustomerEventFactory.getFlightCustomerEvents(flightId, UCI);\n storedCustomerEvents.forEach(function (customerEvent) {\n var item = JSON.parse(JSON.stringify(toolKitItems.find(function (x) {\n return x.Id == customerEvent.ToolkitItemId;\n })));\n item.CustomerEvent = customerEvent;\n customerEvents.push(item);\n });\n return customerEvents;\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/OneStopShop/toolkit.tpl.html',\n scope: {\n flight: \"=\",\n passenger: \"=\",\n treatmentAvailability: \"&onTreatmentAvailability\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('philoxeniaQuestions', philoxeniaQuestions);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name philoxeniaQuestions\r\n * @restrict E\r\n * @description\r\n * Implementation of philoxenia questions \r\n *\r\n * Display the philoxenia questions Panel\r\n * @attr {String} flight-id\r\n * @example\r\n * Usage:\r\n * \r\n * \r\n * @ngInject\r\n */\n\n function philoxeniaQuestions(PhiloxeniaQuestionsFactory) {\n /**\r\n * Initialize philoxeniaQuestions\r\n * @memberof philoxeniaQuestions\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\n function link(scope, element, attributes) {\n scope.togglePanel = togglePanel;\n scope.hasPhiloxeniaData = true;\n scope.philoxeniaData = null;\n scope.showPanel = showPanel();\n initializePanel();\n /**\r\n * Initialize Form Values\r\n * @memberof philoxeniaQuestions\r\n */\n\n function initializePanel() {\n var flightQuestions = PhiloxeniaQuestionsFactory.getFlightPhiloxeniaQuestionsFromStorage(+scope.flightId);\n\n if (!flightQuestions || !flightQuestions.Questions > 0 || !flightQuestions.RepliesCounter > 0) {\n scope.hasPhiloxeniaData = false;\n } else {\n scope.hasPhiloxeniaData = true;\n scope.philoxeniaData = flightQuestions;\n }\n }\n\n function showPanel() {\n var retVal = false;\n var now = moment.utc();\n var std = moment.utc(scope.std);\n var isAfter = now.isAfter(std);\n\n if (isAfter) {\n retVal = true;\n }\n\n return retVal;\n }\n /**\r\n * Toggle Panel\r\n * @memberof philoxeniaQuestions\r\n * @param {number} panelId\r\n */\n\n\n function togglePanel(panelId) {\n $('#' + panelId).toggle();\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/directives/philoxeniaQuestions.tpl.html',\n scope: {\n flightId: '@',\n std: '@'\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('PhiloxeniaQuestionsFactory', PhiloxeniaQuestionsFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PhiloxeniaQuestionsFactory\r\n * @ngInject\r\n */\n\n function PhiloxeniaQuestionsFactory(GenericService) {\n function PhiloxeniaQuestions() {\n this.FlightId = null;\n this.Questions = null;\n this.RepliesCounter = 0;\n }\n\n var objType = 'philoxeniaQuestions';\n var objCallback = PhiloxeniaQuestions;\n var ratingQuestions = [{\n Option: 1,\n OptionText: \"Basic\",\n Counter: 0,\n Percentage: null\n }, {\n Option: 2,\n OptionText: \"Basic +\",\n Counter: 0,\n Percentage: null\n }, {\n Option: 3,\n OptionText: \"Expected\",\n Counter: 0,\n Percentage: null\n }, {\n Option: 4,\n OptionText: \"Expected +\",\n Counter: 0,\n Percentage: null\n }, {\n Option: 5,\n OptionText: \"Excellent\",\n Counter: 0,\n Percentage: null\n }];\n var service = {\n updatePhiloxeniaQuestionsToStorage: updatePhiloxeniaQuestionsToStorage,\n getFlightPhiloxeniaQuestionsFromStorage: getFlightPhiloxeniaQuestionsFromStorage,\n cleanOldData: cleanOldData\n };\n /**\r\n * Get Philoxenia Questions.\r\n * @memberof PhiloxeniaQuestionsFactory\r\n * @returns {Array} PhiloxeniaQuestions \r\n */\n\n function getPhiloxeniaQuestionsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save Philoxenia Questions to storage\r\n * @memberof PhiloxeniaQuestionsFactory\r\n * @param {Array} PhiloxeniaQuestions\r\n */\n\n\n function setPhiloxeniaQuestionsToStorage(objList) {\n GenericService.saveAll(objList, objType);\n }\n /**\r\n * Update Philoxenia Questions for specified flight\r\n * @memberof PhiloxeniaQuestionsFactory\r\n * @param {} PhiloxeniaQuestions questions for a flight\r\n * @returns {Array} PhiloxeniaQuestions\r\n */\n\n\n function updatePhiloxeniaQuestionsToStorage(philoxeniaQuestions) {\n //Get all PhiloxeniaQuestions exept current flight from storage\n var storedPhiloxeniaQuestions = getPhiloxeniaQuestionsFromStorage();\n var storedPhiloxeniaQuestionsFiltered = storedPhiloxeniaQuestions.filter(function (f) {\n return f != null && f.FlightId != philoxeniaQuestions.FlightId;\n }); //Add Philoxenia Questions for the current flight\n\n if (philoxeniaQuestions) {\n //get AVG value for Rating questions\n philoxeniaQuestions.Questions.forEach(function (question) {\n if (question.QuestionInfo.Type == \"RATING\") {\n //Get Option List\n var optionList = [];\n ratingQuestions.forEach(function (option) {\n var currentAnswer = question.AnswerCounters.filter(function (f) {\n return f.OptionId == option.Option;\n });\n\n if (currentAnswer.length > 0 && philoxeniaQuestions.RepliesCounter > 0) {\n option.Counter = currentAnswer[0].Counter;\n option.Percentage = currentAnswer[0].Counter / philoxeniaQuestions.RepliesCounter * 100;\n }\n\n optionList.push(option);\n });\n question.OptionList = optionList; //Get AVG value\n\n var value = 0;\n var weight = 0;\n question.AnswerCounters.forEach(function (answer) {\n value += +answer.TextValue * answer.Counter;\n weight += answer.Counter;\n });\n\n if (weight > 0) {\n question.AVG = value / weight;\n }\n } else {\n var selectedOptionIds = question.AnswerCounters.map(function (v) {\n return v.OptionId;\n }); //get AnswerCounter for selections with zero counter\n\n var optionsZeroCounter = question.QuestionInfo.Options.filter(function (x) {\n return !selectedOptionIds.includes(x.Id);\n });\n var optionsZeroCounterMapper = optionsZeroCounter.map(function (a) {\n return {\n OptionId: a.Id,\n TextValue: a.Value,\n Counter: 0\n };\n });\n question.AnswerCounters = question.AnswerCounters.concat(optionsZeroCounterMapper);\n question.AVG = 0;\n }\n }); //Get only questions with answers\n\n philoxeniaQuestions.Questions = philoxeniaQuestions.Questions.filter(function (f) {\n return f.AnswerCounters && f.AnswerCounters.length > 0;\n });\n storedPhiloxeniaQuestionsFiltered.push(philoxeniaQuestions); //save PhiloxeniaQuestions\n\n setPhiloxeniaQuestionsToStorage(storedPhiloxeniaQuestionsFiltered);\n }\n }\n /**\r\n * Get Philoxenia Questions for specified flight\r\n * @memberof PhiloxeniaQuestionsFactory\r\n * @param {number} flightId\r\n * @returns {Array} PhiloxeniaQuestions\r\n */\n\n\n function getFlightPhiloxeniaQuestionsFromStorage(flightId) {\n var storedPhiloxeniaQuestions = getPhiloxeniaQuestionsFromStorage();\n\n if (storedPhiloxeniaQuestions) {\n var flightPhiloxeniaQuestions = storedPhiloxeniaQuestions.filter(function (x) {\n return x != null && x.FlightId == flightId;\n });\n return flightPhiloxeniaQuestions[0];\n } else {\n return null;\n }\n }\n /**\r\n * Clean ls from old flights Philoxenia Questions\r\n * @param {array} flights Synced flights\r\n */\n\n\n function cleanOldData(responseFlightIds) {\n var previousPhiloxeniaQuestions = getPhiloxeniaQuestionsFromStorage(); //Filter out Philoxenia Questions of old flights\n\n previousPhiloxeniaQuestions = previousPhiloxeniaQuestions.filter(function (x) {\n return x != null && responseFlightIds.includes(x.FlightId);\n });\n setPhiloxeniaQuestionsToStorage(previousPhiloxeniaQuestions);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CabinReportLocalEditFactory', CabinReportLocalEditFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportLocalEditFactory\r\n * @description \r\n * Manage Local Cabin Reports.\r\n * @ngInject\r\n */\n\n function CabinReportLocalEditFactory($log, localStorageMD5Service, CCMSFactory, LogService, UserFactory, GenericService, GroundServicesFactory, BarTrolleyFactory, enableWaterUpliftReporting, waterUpliftSupportingAcTypes) {\n /**\r\n * Initialiaze CabinReportLocalEdit object \r\n * @memberof CabinReportLocalEditFactory\r\n */\n function CabinReportLocalEdit() {\n this.ReportGuid = null;\n this.AuthorId = null;\n this.AuthorAimsId = null;\n this.AuthorName = null;\n this.Created = null;\n this.FlightAimsId = null;\n this.FlightId = null;\n this.LastUpdated = null;\n this.Departure = null;\n this.Arrival = null;\n this.AcType = null;\n this.AcTailNo = null;\n this.FlightDate = null;\n this.FlightNo = null; //v1.1 added pax and dep/arr details\n\n this.BookedC = null;\n this.BookedY = null;\n this.BookedInf = null;\n this.BookedPad = null;\n this.BookedChld = null;\n this.ActualC = null;\n this.ActualY = null;\n this.ActualInf = null;\n this.ActualPad = null;\n this.ActualChld = null;\n this.DepartureICAO = null;\n this.DepartureCountry = null;\n this.DepartureName = null;\n this.ArrivalICAO = null;\n this.ArrivalCountry = null;\n this.ArrivalName = null;\n this.ScheduledDeparture = null;\n this.ScheduledDepartureDateUTC = null;\n this.ScheduledDepartureTimeUTC = null;\n this.Departure = null;\n this.Arrival = null;\n this.ReportId = null;\n this.Status = null; // pending, draft, completed, synched\n\n this.IsValid = false; //new fields\n\n this.DepartureGate = null;\n this.DepartureTimezone = null;\n this.ArrivalTimezone = null;\n this.CallSign = null;\n this.ScheduledArrival = null;\n this.ActiveVariousIssues = 0;\n this.WarningVariousIssues = 0;\n this.CCMSCrewPositions = [];\n this.CCMSCrewPositionsIsValid = false;\n this.CCMSCrewPositionsErrorMessage = null;\n this.FlightReportSubmittedBy1L = true;\n this.CrewRemarks = null;\n this.ItemsFoundDescription = null;\n this.ItemsFoundAgent = null;\n this.ItemsFoundSignature = null;\n this.ItemsFoundSectionHasValue = false;\n this.ItemsFoundSectionIsValid = false;\n this.UMNumber = 0;\n this.UMDescription = null;\n this.UMAgent = null;\n this.UMSignature = null;\n this.UMSectionHasValue = false;\n this.UMSectionIsValid = false;\n this.WaterUpliftSuggestedQuantity = null;\n this.WaterUpliftInitial = null;\n this.WaterUpliftRemarks = null;\n this.WaterSectionHasValue = false;\n this.WaterSectionIsValid = false;\n this.GroundServicesSectionHasValue = false;\n this.BarTrolleys = [];\n this.BarTrolleysIsValid = false;\n this.FirstAidKits = [];\n this.FirstAidKitsIsValid = [];\n this.MedicalIncidents = [];\n this.MedicalIncidentsIsValid = [];\n this.SpecialMealIssues = [];\n this.SpecialMealIssuesIsValid = false;\n this.Supplies = [];\n this.SuppliesIsValid = false;\n this.SuppliesErrorMessage = null;\n this.TravelValueSeals = [];\n this.TravelValueSealsIsValid = false;\n this.TravelValueIncomplete = false;\n this.TravelValueIncompleteRow = null;\n this.TravelValueIncompleteReason = null;\n this.TravelValueRemarks = null;\n this.Remarks = null;\n this.VariousIssues = []; //v1.1 :: used to hold all crew (fd, cabin & dhc)\n\n this.crew = null;\n this.Route = null;\n this.DutyDate = null;\n this.getDescription = getDescription;\n this.getRoute = getRoute;\n this.updateTotals = updateTotals;\n this.validateCCMS = validateCCMS;\n this.getCCMSObj = getCCMSObj;\n this.saveReport = saveReport;\n this.saveReportAsTemp = saveReportAsTemp;\n this.getRemaining = getRemaining;\n this.ArrivalGroundServices = [];\n this.DepartureGroundServices = [];\n this.UpgradedPassengers = [];\n this.ChangedSeats = [];\n this.IncompleteServices = [];\n this.IncompleteServicesIsValid = false; //this.BoardingTimes = null;\n\n this.BoardingTimesRemarks = null;\n this.FirstPaxTime = null;\n this.LastPaxTime = null;\n this.showBarTrolleyUploadImage = true;\n this.showBarTrolleyInsertData = true;\n this.disableBarTrolleysPhotoRemarks = true;\n this.LuggageNumber = 0;\n this.LuggageDescription = null;\n this.GetId = GetId;\n this.GroomingReports = [];\n }\n\n var objType = 'cabinReportLocalEdits';\n var objCallback = CabinReportLocalEdit;\n var service = {\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n getCabinReportsFromStorage: getCabinReportsFromStorage,\n setCabinReportsToStorage: setCabinReportsToStorage,\n deleteTempReport: deleteTempReport,\n getPreviousCabinReportCcmsPositions: getPreviousCabinReportCcmsPositions,\n deleteReport: deleteReport,\n setCabinReportToStorage: setCabinReportToStorage,\n getCabinReportLocalEditFromTemp: getCabinReportLocalEditFromTemp,\n getCabinReportLocalEditForFlight: getCabinReportLocalEditForFlight,\n getCabinReportLocalEdit: getCabinReportLocalEdit,\n getCabinReportLocalEditCountThatNeedToBeSynched: getCabinReportLocalEditCountThatNeedToBeSynched,\n IsExistForRouteDutyDate: IsExistForRouteDutyDate,\n getCabinReportLocalEditThatNeedToBeSynched: getCabinReportLocalEditThatNeedToBeSynched,\n getNewReport: getNewReport,\n markReportAsSynched: markReportAsSynched,\n checkForNewGroundServices: checkForNewGroundServices,\n getFlightIdsWithPendingReports: getFlightIdsWithPendingReports,\n getGroomingReports: getGroomingReports\n };\n\n function getGroomingReports() {\n var allReports = getCabinReportsFromStorage();\n var groomingReports = [];\n allReports.forEach(function (report) {\n if (report.GroomingReports) {\n report.GroomingReports.forEach(function (groomingReport) {\n if (!groomingReport.isSynced) {\n groomingReports.push({\n reportGuid: report.ReportGuid,\n crewId: groomingReport.crewId,\n groomingCategoryId: groomingReport.groomingCategoryId,\n feedback: groomingReport.feedback,\n isSynced: groomingReport.isSynced\n });\n }\n });\n }\n });\n return groomingReports;\n }\n /**\r\n * Overide default get Id\r\n * @memberof CabinReportLocalEditFactory\r\n * @returns {string} ReportGuid \r\n */\n\n\n function GetId() {\n return this.ReportGuid;\n }\n /**\r\n * Get a short Description of this cabin report\r\n * @memberof CabinReportLocalEditFactory\r\n * @returns {string} Description \r\n */\n\n\n function getDescription() {\n var s = this.FlightNo + ' ' + this.Departure + '-' + this.Arrival + ' ' + this.ScheduledDepartureDateUTC + ' by ' + this.AuthorName;\n return s;\n }\n /**\r\n * Get the Route of this cabin report\r\n * @memberof CabinReportLocalEditFactory\r\n * @returns {string} Route \r\n */\n\n\n function getRoute() {\n if (this.Departure == null && this.Arrival == null) return '-';else return (this.Departure || '?') + '-' + (this.Arrival || '?');\n }\n /**\r\n * Update the totals of all the section of the report\r\n * @memberof CabinReportLocalEditFactory\r\n */\n\n\n function updateTotals() {\n // check the various issues\n var allActiveVariousIssues = 0;\n var allWarningVariousIssues = 0;\n var variousItemCount = this.VariousIssues.length;\n\n for (var i = 0; i < variousItemCount; i++) {\n if (this.VariousIssues[i].ItemHasValue == true) {\n if (this.VariousIssues[i].ItemValue != null && this.VariousIssues[i].ItemValue != '') {\n allActiveVariousIssues++;\n } else {\n allWarningVariousIssues++;\n }\n }\n }\n\n this.ActiveVariousIssues = allActiveVariousIssues;\n this.WarningVariousIssues = allWarningVariousIssues; // check if the report is valid\n\n this.IsValid = true; // various issues\n\n if (this.WarningVariousIssues > 0) {\n this.IsValid = false;\n } // ccms crew positions\n\n\n this.CCMSCrewPositionsIsValid = true;\n\n for (var i = 0; i < this.CCMSCrewPositions.length; i++) {\n if (this.CCMSCrewPositions[i].CrewId == null || this.CCMSCrewPositions[i].CrewId == '' ||\n /*(this.CCMSCrewPositions[i].Initials == null) || (this.CCMSCrewPositions[i].Initials == '') ||*/\n //AIMS has crew with empty 3ltr code\n this.CCMSCrewPositions[i].Name == null || this.CCMSCrewPositions[i].Name == '' || this.CCMSCrewPositions[i].Position == null || this.CCMSCrewPositions[i].Position == '') {\n this.IsValid = false;\n this.CCMSCrewPositionsIsValid = false;\n }\n }\n\n if (!this.validateCCMS()) {\n this.IsValid = false;\n this.CCMSCrewPositionsIsValid = false;\n }\n\n this.FlightReportSubmittedBy1L = false;\n var user = UserFactory.getUser();\n\n if (user.position == \"FA\") {\n this.FlightReportSubmittedBy1L = true;\n } else {\n for (var i = 0; i < this.CCMSCrewPositions.length; i++) {\n if (user.aimsId == this.CCMSCrewPositions[i].CrewId && (this.CCMSCrewPositions[i].CCMS == \"1L\" || this.CCMSCrewPositions[i].CCMS == null || this.CCMSCrewPositions[i].CCMS == \"\")) {\n this.FlightReportSubmittedBy1L = true;\n break;\n }\n }\n } // items found\n\n\n this.ItemsFoundSectionIsValid = true;\n this.ItemsFoundSectionHasValue = false;\n\n if (this.ItemsFoundDescription != null && this.ItemsFoundDescription != '' || this.ItemsFoundAgent != null && this.ItemsFoundAgent != '' || this.ItemsFoundSignature != null && this.ItemsFoundSignature != '') {\n this.ItemsFoundSectionHasValue = true;\n\n if (!(this.ItemsFoundDescription != null && this.ItemsFoundDescription != '' && this.ItemsFoundAgent != null && this.ItemsFoundAgent != '' && this.ItemsFoundSignature != null && this.ItemsFoundSignature != '')) {\n this.IsValid = false;\n this.ItemsFoundSectionIsValid = false;\n }\n } // unaccompanied minors\n\n\n this.UMSectionIsValid = true;\n this.UMSectionHasValue = false;\n this.UMNumber = parseInt(this.UMNumber);\n if (isNaN(this.UMNumber)) this.UMNumber = 0; //UM has a value, if UMNo > 0\n\n if (this.UMNumber != null && this.UMNumber > 0) this.UMSectionHasValue = true; //UM is invalid, if it has a value but not all required fields are in place\n\n if (this.UMSectionHasValue && (this.UMAgent == null || this.UMAgent == '' || this.UMSignature == null || this.UMSignature == '')) {\n this.IsValid = false;\n this.UMSectionIsValid = false;\n } // luggage \n\n\n this.LuggageSectionIsValid = true;\n this.LuggageSectionHasValue = false;\n this.LuggageNumber = parseInt(this.LuggageNumber);\n if (isNaN(this.LuggageNumber)) this.LuggageNumber = 0; //Luggage has a value, if LuggageNo > 0\n\n if (this.LuggageNumber != null && this.LuggageNumber > 0) this.LuggageSectionHasValue = true;\n var today = new Date(this.FlightDate);\n this.WaterSectionIsValid = true;\n this.WaterSectionHasValue = false;\n\n if (enableWaterUpliftReporting && (this.WaterUpliftInitial != null && this.WaterUpliftInitial != '' || this.WaterUpliftRemarks != null && this.WaterUpliftRemarks != '' || (today.getDate() == 1 || today.getDate() == 15) && waterUpliftSupportingAcTypes.includes(this.AcType))) {\n this.WaterSectionHasValue = true;\n\n if (!(this.WaterUpliftInitial != null && this.WaterUpliftInitial != '')) {\n this.IsValid = false;\n this.WaterSectionIsValid = false;\n } else {\n this.WaterSectionIsValid = true;\n }\n }\n\n this.GroundServicesSectionHasValue = false;\n\n if (this.ArrivalGroundServices) {\n for (var i = 0; i < this.ArrivalGroundServices.length; i++) {\n if (this.ArrivalGroundServices[i].Used) {\n this.GroundServicesSectionHasValue = true;\n }\n }\n }\n\n if (this.DepartureGroundServices) {\n for (var i = 0; i < this.DepartureGroundServices.length; i++) {\n if (this.DepartureGroundServices[i].Used) {\n this.GroundServicesSectionHasValue = true;\n }\n }\n } // bar/trolleys\n\n\n this.BarTrolleysIsValid = true;\n\n for (var i = 0; i < this.BarTrolleys.length; i++) {\n if ((this.BarTrolleys[i].Position == null || this.BarTrolleys[i].Position == '') && this.BarTrolleys[i].Photos.length == 0) {\n BarTrolleyFactory.deleteFromList(this.BarTrolleys[i], this.BarTrolleys); //this.IsValid = false;\n //this.BarTrolleysIsValid = false;\n }\n }\n\n showOrHideBarTrolleyInputs(this); // first aid kits\n\n this.FirstAidKitsIsValid = true;\n\n for (var i = 0; i < this.FirstAidKits.length; i++) {\n if (this.FirstAidKits[i].Position == null || this.FirstAidKits[i].Position == '') {\n this.IsValid = false;\n this.FirstAidKitsIsValid = false;\n }\n } // medical incidents\n\n\n this.MedicalIncidentsIsValid = true;\n\n for (var i = 0; i < this.MedicalIncidents.length; i++) {\n if (this.MedicalIncidents[i].Name == null || this.MedicalIncidents[i].Name == '' || this.MedicalIncidents[i].FAKUsed == null || this.MedicalIncidents[i].FAKUsed == '' || this.MedicalIncidents[i].Symptoms == null || this.MedicalIncidents[i].Symptoms == '' || this.MedicalIncidents[i].DoctorInvolved == null || this.MedicalIncidents[i].DoctorInvolved == '') {\n this.IsValid = false;\n this.MedicalIncidentsIsValid = false;\n }\n } // special meals issues\n\n\n this.SpecialMealIssuesIsValid = true;\n\n for (var i = 0; i < this.SpecialMealIssues.length; i++) {\n if (this.SpecialMealIssues[i].Name == null || this.SpecialMealIssues[i].Name == '' || this.SpecialMealIssues[i].Source == null || this.SpecialMealIssues[i].Source == '' || this.SpecialMealIssues[i].MealType == null || this.SpecialMealIssues[i].MealType == '') {\n this.IsValid = false;\n this.SpecialMealIssuesIsValid = false;\n }\n } // supplies\n\n\n this.SuppliesIsValid = true;\n this.SuppliesErrorMessage = null;\n\n for (var i = 0; i < this.Supplies.length; i++) {\n if (this.Supplies[i].SupplyType == null || this.Supplies[i].SupplyType == '' || this.Supplies[i].SupplyType == '-') {\n this.IsValid = false;\n this.SuppliesIsValid = false;\n }\n\n for (var j = 0; j < this.Supplies.length; j++) {\n if (this.Supplies[i].Id != this.Supplies[j].Id && this.Supplies[i].SupplyType == this.Supplies[j].SupplyType) {\n this.IsValid = false;\n this.SuppliesIsValid = false;\n this.SuppliesErrorMessage = \"You cannot have the same supply issue more than once.\";\n }\n }\n } // travel value seals\n\n\n this.TravelValueSealsIsValid = true;\n\n for (var i = 0; i < this.TravelValueSeals.length; i++) {\n if (this.TravelValueSeals[i].Position == null || this.TravelValueSeals[i].Position == '') {\n this.IsValid = false;\n this.TravelValueSealsIsValid = false;\n }\n } // travel value incomplete\n\n\n this.TravelValueIncompleteIsValid = true;\n this.TravelValueIncompleteErrorMessage = null;\n\n if (this.TravelValueIncomplete) {\n // \"0\" == \"\" so use === for comparison to empty string\n if (typeof this.TravelValueIncompleteRow == \"undefined\" || this.TravelValueIncompleteRow === \"\" || this.TravelValueIncompleteRow == null) {\n this.TravelValueIncompleteIsValid = false;\n this.TravelValueIncompleteErrorMessage = \"Travel Value Stopped at row is required\";\n } else if (typeof this.TravelValueIncompleteReason == \"undefined\" || this.TravelValueIncompleteReason == \"\" || this.TravelValueIncompleteReason == null) {\n this.TravelValueIncompleteIsValid = false;\n this.TravelValueIncompleteErrorMessage = \"Travel Value Incomplete Reason is required\";\n }\n } // Incomplete Services \n\n\n this.IncompleteServicesIsValid = true;\n\n for (var i = 0; i < this.IncompleteServices.length; i++) {\n if (this.IncompleteServices[i].ServiceClass == null || this.IncompleteServices[i].FromRowNo == '' || this.IncompleteServices[i].ToRowNo == '' || this.IncompleteServices[i].ServiceType == '' || this.IncompleteServices[i].Reason == '' || this.IncompleteServices[i].FromRowNo > this.IncompleteServices[i].ToRowNo) {\n this.IsValid = false;\n this.IncompleteServicesIsValid = false;\n }\n }\n }\n /**\r\n * Validate the Crew Positions\r\n * @memberof CabinReportLocalEditFactory\r\n */\n\n\n function validateCCMS() {\n this.CCMSCrewPositionsErrorMessage = null;\n var valuesInError = new Array();\n\n for (var i = 0; i < this.CCMSCrewPositions.length; i++) {\n if (this.CCMSCrewPositions[i].CCMS == null || this.CCMSCrewPositions[i].CCMS == '') {\n this.CCMSCrewPositionsErrorMessage = \"You must fill CCMS for all crew members\";\n return false;\n }\n }\n\n var allCCMSPositions = CCMSFactory.getCCMSFromStorage(); // if not multiple then this position must not be found in another\n // place in the array\n\n var multiplePositionsInError = new Array();\n\n for (var i = 0; i < this.CCMSCrewPositions.length; i++) {\n var ccmsObj_i = this.getCCMSObj(allCCMSPositions, this.CCMSCrewPositions[i].CCMS);\n\n if (ccmsObj_i.ccmsPositionsIsValid) {\n var ccms_i = ccmsObj_i.ccms;\n\n if (ccms_i.Multiple == false) {\n for (var j = 0; j < this.CCMSCrewPositions.length; j++) {\n var ccmsObj_j = this.getCCMSObj(allCCMSPositions, this.CCMSCrewPositions[j].CCMS);\n\n if (ccmsObj_j.ccmsPositionsIsValid) {\n var ccms_j = ccmsObj_j.ccms;\n\n if (this.CCMSCrewPositions[i].CrewId != this.CCMSCrewPositions[j].CrewId) {\n if (ccms_i.Position == ccms_j.Position) {\n if (multiplePositionsInError.indexOf(ccms_i.Position) < 0) multiplePositionsInError.push(ccms_i.Position);\n }\n }\n }\n }\n }\n } else {\n valuesInError.push(this.CCMSCrewPositions[i].CCMS);\n this.CCMSCrewPositions[i].CCMS = null;\n }\n }\n\n if (valuesInError.length == 1) {\n this.CCMSCrewPositionsErrorMessage = \"You cannot assigned the position \" + valuesInError + \" in this flight\";\n } else if (valuesInError.length > 1) {\n this.CCMSCrewPositionsErrorMessage = \"You cannot assigned the positions \" + valuesInError + \" in this flight\";\n }\n\n if (multiplePositionsInError.length > 0) {\n var multiplePositionError = \"\";\n\n for (var i = 0; i < multiplePositionsInError.length; i++) {\n if (multiplePositionError != \"\") {\n multiplePositionError = multiplePositionError + \", \";\n }\n\n multiplePositionError = multiplePositionError + multiplePositionsInError[i];\n }\n\n if (multiplePositionsInError.length == 1) this.CCMSCrewPositionsErrorMessage = \"You have assigned the position \" + multiplePositionError + \" multiple times\";else this.CCMSCrewPositionsErrorMessage = \"You have assigned the positions \" + multiplePositionError + \" multiple times\";\n }\n\n if (this.CCMSCrewPositionsErrorMessage != null) return false;else return true;\n }\n /**\r\n * Get the CCMS Positions of this aircraft\r\n * @memberof CabinReportLocalEditFactory\r\n */\n\n\n function getCCMSObj(ccms, pos) {\n var AcTypeIsValid = false;\n var ccmsPositionsIsValid = false;\n var ccmsObj = null;\n\n for (var i = 0; i < ccms.length; i++) {\n // find the positions for this aircraft type\n if (ccms[i].Aircraft == this.AcType) {\n AcTypeIsValid = true;\n\n for (var j = 0; j < ccms[i].Positions.length; j++) {\n if (ccms[i].Positions[j].Position == pos) {\n ccmsObj = ccms[i].Positions[j];\n ccmsPositionsIsValid = true;\n }\n }\n }\n }\n\n if (!AcTypeIsValid) {\n var log = \"CCMS , POS=\" + this.CCMSCrewPositions[j].CCMS + \", Ac=\" + this.AcType + \", all=\" + JSON.stringify(allCCMSPositions);\n log = log.replace(/\"Multiple\":/g, \"\").replace(/\"Position\":/g, \"\").replace(/\"Aircraft\"/g, \"AC\").replace(/true/g, 1).replace(/false/g, 0).replace(/\"/g, \"\").replace(/Positions/g, \"Ps\");\n LogService.debug(log);\n }\n\n return {\n AcTypeIsValid: AcTypeIsValid,\n ccmsPositionsIsValid: ccmsPositionsIsValid,\n ccms: ccmsObj\n };\n }\n /**\r\n * Save the Cabin Report\r\n * @memberof CabinReportLocalEditFactory\r\n */\n\n\n function saveReport() {\n // update the LastUpdated field\n this.LastUpdated = new Date(); // get the reports array from storage\n\n var allReports = getCabinReportsFromStorage();\n if (allReports == null) allReports = new Array(); // find the current report from the array (if present)\n\n var arrayLength = allReports.length;\n var reportIndex = -1;\n\n for (var i = 0; i < arrayLength; i++) {\n if (allReports[i].ReportGuid == this.ReportGuid) {\n reportIndex = i;\n break;\n }\n } // add or update a copy of the current report\n\n\n if (reportIndex >= 0) allReports[reportIndex] = this;else allReports.push(this); // save\n\n setCabinReportsToStorage(allReports);\n }\n /**\r\n * Save the Report As Temp\r\n * @memberof CabinReportLocalEditFactory\r\n */\n\n\n function saveReportAsTemp() {\n // update the LastUpdated field\n this.LastUpdated = new Date(); // save as temp\n\n localStorageMD5Service.remove('cabinReportLocalEdit_TEMP');\n localStorageMD5Service.set('cabinReportLocalEdit_TEMP', this);\n }\n /**\r\n * Get the remaining characters of this field\r\n * @memberof CabinReportLocalEditFactory\r\n */\n\n\n function getRemaining(max, text) {\n if (typeof text === \"undefined\" || text === null) return '';\n if (typeof max === \"undefined\" || max === null || max < 0 || !max) max = 5000;\n var length = text.length;\n /*var matches = text.match(/\\n/g);\r\n if (matches)\r\n \tlength += matches.length;*/\n //if(max > length)\n\n return 'characters left: ' + (max - length); //else\n //\treturn '-full-';\n } //Factory functions\n\n /**\r\n * Extend Object from the default local Cabin Report Object\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {Object} obj a CabinReportLocalEdit\r\n * @returns {Object} CabinReportLocalEdit\r\n */\n\n\n function fromObject(obj) {\n return GenericService.fromObject(obj, objCallback);\n }\n /**\r\n * Extend Object List from the default local Cabin Report Object\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {Array} objList a CabinReportLocalEdit list\r\n * @returns {Array} CabinReportLocalEdits\r\n */\n\n\n function fromObjectList(objList) {\n return GenericService.fromObjectList(objList, objCallback);\n }\n /**\r\n * Get Cabin Reports from storage\r\n * @memberof CabinReportLocalEditFactory\r\n * @returns {Array} CabinReports\r\n */\n\n\n function getCabinReportsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save Cabin Reports to storage\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {Array} cabinReportLocalEdits A list of Cabin Reports \r\n */\n\n\n function setCabinReportsToStorage(cabinReportLocalEdits) {\n GenericService.saveAll(cabinReportLocalEdits, objType, objCallback);\n }\n /**\r\n * Delete Cabin Temporary Report from storage\r\n * @memberof CabinReportLocalEditFactory\r\n */\n\n\n function deleteTempReport() {\n localStorageMD5Service.remove('cabinReportLocalEdit_TEMP');\n }\n /**\r\n * Get the CCMS positions of the previous flight\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {string} guid The report GUID\r\n * @param {string} acNo The Aircaft Number\r\n * @param {string} flightDateUTC The flight date in UTC\r\n * @param {string} flightTimeUTC The flight time in UTC\r\n * @return {Array} CCMSpositions\r\n */\n\n\n function getPreviousCabinReportCcmsPositions(guid, acNo, flightDateUTC, flightTimeUTC) {\n var previousCcms = null;\n\n try {\n var flightDate = new Date(flightDateUTC + ' ' + flightTimeUTC); //date of ref flight\n\n var flightDateMatch = null;\n var flightDateCheck = null;\n var previousRep = null;\n var report = null;\n var reports = getCabinReportsFromStorage(); //console.debug('Find previous report for ' + acNo + ' ' + flightDateUTC + ' ' + flightTimeUTC);\n\n if (reports != null && reports.length > 0) {\n //loop all reports to find the previous one based on the input data\n var x;\n\n for (var i = 0; i < reports.length; i++) {\n report = reports[i];\n flightDateCheck = new Date(report.ScheduledDepartureDateUTC + \" \" + report.ScheduledDepartureTimeUTC); //console.debug('\t' + report.AcTailNo + ' ' + report.FlightNo + ' ' + report.Departure + '-' + report.Arrival + ' ' + report.ScheduledDepartureDateUTC + \" \" + report.ScheduledDepartureTimeUTC);\n //flight too old to be \"previous\"\n\n if ((flightDate - flightDateCheck) / 1000 / 60 / 60 > 6) {\n x = 0; //console.debug('\t\tpast flight, not acceptable');\n } //same report as ref one\n else if (report.ReportGuid == guid) {\n x = 1; //console.debug('\t\tsame report');\n } //worse match than current one\n else if (flightDateMatch != null && flightDateCheck < flightDate && flightDateMatch < flightDateCheck) {\n x = 2; //console.debug('\t\tprevious match is a closer one');\n } //later than ref flight\n else if (flightDate < flightDateCheck) {\n x = 3; //console.debug('\t\tlater than ref flight');\n } //match!\n else {\n //console.debug('\t\tcandidate');\n //store selected report\n previousRep = report;\n flightDateMatch = flightDateCheck;\n }\n }\n }\n\n if (previousRep != null && previousRep.CCMSCrewPositions != null && previousRep.CCMSCrewPositions.length > 0) {\n previousCcms = previousRep.CCMSCrewPositions;\n }\n } catch (e) {\n console.error(e);\n }\n\n return previousCcms;\n }\n /**\r\n * Delete Selected repport\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {string} reportGuid The report's Identifier\r\n */\n\n\n function deleteReport(reportGuid) {\n GenericService.remove(reportGuid, objType, objCallback);\n }\n /**\r\n * Save Selected Cabin repport\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {Object} report A Cabin Report\r\n */\n\n\n function setCabinReportToStorage(report) {\n GenericService.save(report, objType, objCallback);\n }\n /**\r\n * Get Temporary Cabin repport\r\n * @memberof CabinReportLocalEditFactory\r\n * @return {Object} report \r\n */\n\n\n function getCabinReportLocalEditFromTemp() {\n var cabinReportLocalEdit = localStorageMD5Service.get('cabinReportLocalEdit_TEMP');\n cabinReportLocalEdit = checkForNewGroundServices(cabinReportLocalEdit);\n return fromObject(cabinReportLocalEdit);\n }\n /**\r\n * Get the Cabin repport of this flight\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {number} flightId A flight Id\r\n * @return {Object} report \r\n */\n\n\n function getCabinReportLocalEditForFlight(flightId) {\n var cabinReportLocalEdits = getCabinReportsFromStorage();\n if (cabinReportLocalEdits == null) return null;\n var result = null;\n var arrayLength = cabinReportLocalEdits.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (cabinReportLocalEdits[i].FlightId == flightId) {\n result = cabinReportLocalEdits[i];\n break;\n }\n }\n\n result = checkForNewGroundServices(result);\n return result;\n }\n /**\r\n * add any new ground services from storage to the existing report\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {Object} report\r\n * @return {Object} report \r\n */\n\n\n function checkForNewGroundServices(report) {\n if (report == null) return report;\n var depStorageGroundServices = GroundServicesFactory.getGroundServicesByStation(report.Departure); //var arrStorageGroundServices = GroundServicesFactory.getGroundServicesByStation(report.Arrival);\n\n for (var i = 0; i < depStorageGroundServices.length; i++) {\n var found = false;\n\n for (var j = 0; j < report.DepartureGroundServices.length; j++) {\n if (depStorageGroundServices[i].ServiceType === report.DepartureGroundServices[j].ServiceType) {\n //this ground service is available according to the localstorage but its not in the report\n found = true;\n break;\n }\n }\n\n if (!found) {\n report.DepartureGroundServices.push(depStorageGroundServices[i]);\n }\n } //Disable arrival ground services from report:\n // for (var i = 0; i < arrStorageGroundServices.length; i++) {\n // \tvar found = false;\n // \tfor (var j = 0; j < report.ArrivalGroundServices.length; j++){\n // \t\tif (arrStorageGroundServices[i].ServiceType === report.ArrivalGroundServices[j].ServiceType){\n // \t\t\t//this ground service is available according to the localstorage but its not in the report\n // \t\t\tfound = true;\n // \t\t\tbreak;\n // \t\t}\n // \t}\n // \tif (!found){\n // \t\treport.ArrivalGroundServices.push(arrStorageGroundServices[i]);\n // \t}\n //}\n\n\n return report;\n }\n /**\r\n * Get the Cabin repport\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {string} reportGuid A report Id\r\n * @return {Object} report \r\n */\n\n\n function getCabinReportLocalEdit(reportGuid) {\n var report = GenericService.get(reportGuid, objType, objCallback);\n report = checkForNewGroundServices(report);\n return report;\n }\n /**\r\n * Get the number of reports that need to be synched\r\n * @memberof CabinReportLocalEditFactory\r\n * @return {number} result A Cabin Report\r\n */\n\n\n function getCabinReportLocalEditCountThatNeedToBeSynched() {\n var cabinReportLocalEdits = getCabinReportsFromStorage();\n if (cabinReportLocalEdits == null) return 0;\n var result = 0;\n\n for (var i = 0; i < cabinReportLocalEdits.length; i++) {\n if (cabinReportLocalEdits[i].Status === 'completed') {\n result++;\n }\n }\n\n return result;\n }\n /**\r\n * Cabin report Exist For Route and DutyDate\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {string} Route The flight's route\r\n * @param {string} Dutydate The flight's duty date\r\n * @return {boolean} result\r\n */\n\n\n function IsExistForRouteDutyDate(Route, Dutydate) {\n var cabinReportLocalEdits = getCabinReportsFromStorage();\n if (cabinReportLocalEdits == null) return false;\n var result = false;\n\n for (var i = 0; i < cabinReportLocalEdits.length; i++) {\n if (cabinReportLocalEdits[i].Route == Route && cabinReportLocalEdits[i].Dutydate) {\n result = true;\n break;\n }\n }\n\n return result;\n }\n /**\r\n * Get the reports that need to be synched\r\n * @memberof CabinReportLocalEditFactory\r\n * @return {array} result \r\n */\n\n\n function getCabinReportLocalEditThatNeedToBeSynched() {\n var result = [];\n var cabinReportLocalEdits = getCabinReportsFromStorage();\n if (cabinReportLocalEdits == null) return result;\n\n for (var i = 0; i < cabinReportLocalEdits.length; i++) {\n if (cabinReportLocalEdits[i].Status === 'completed') {\n result.push(cabinReportLocalEdits[i]);\n }\n }\n\n return result;\n }\n /**\r\n * Gonstructor for a new cabin Report\r\n * @memberof CabinReportLocalEditFactory\r\n * @return {array} result \r\n */\n\n\n function getNewReport() {\n return GenericService.constructor(objCallback);\n }\n /**\r\n * Mark selected report As Synched\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {string} reportGuid The report Guid\r\n * @return {boolean} isSuccess \r\n */\n\n\n function markReportAsSynched(reportGuid) {\n var report = getCabinReportLocalEdit(reportGuid);\n if (report == null) return false;\n report.Status = 'synched';\n report.saveReport();\n return true;\n }\n\n function showOrHideBarTrolleyInputs(report) {\n var photos = report.BarTrolleys.map(function (i) {\n return i.Photos;\n });\n var photosCount = 0;\n\n if (photos[0] != undefined) {\n photosCount = photos[0].length;\n }\n\n report.showBarTrolleyUploadImage = photosCount > 0 || report.BarTrolleys.length == 0;\n report.showBarTrolleyInsertData = !photosCount > 0 || report.BarTrolleys.length == 0;\n report.disableBarTrolleysPhotoRemarks = !photosCount > 0;\n }\n /**\r\n * Get flight ids with pending reports \r\n * @memberof CabinReportLocalEditFactory\r\n * @return [long] List of flight ids \r\n */\n\n\n function getFlightIdsWithPendingReports() {\n var cabinReportLocalEdits = getCabinReportsFromStorage();\n var flightIds = [];\n\n if (cabinReportLocalEdits != null) {\n var now = moment(); //var now = moment('2016-06-14') //For debug;\n\n for (var i = 0; i < cabinReportLocalEdits.length; i++) {\n var flightDate = moment(cabinReportLocalEdits[i].FlightDate);\n\n if (cabinReportLocalEdits[i].Status !== 'stored' && now.diff(flightDate, 'days') < 5) {\n flightIds.push(cabinReportLocalEdits[i].FlightId);\n }\n }\n }\n\n return flightIds;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CabinReportLocalEditCreatorFactory', CabinReportLocalEditCreatorFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportLocalEditCreatorFactory\r\n * @description \r\n * Create a new local Report\r\n * @ngInject\r\n */\n\n function CabinReportLocalEditCreatorFactory(FlightFactory, ReportGuidFactory, CabinReportTemplateItemFactory, CabinReportLocalEditFactory, UserFactory, CCMSCrewPositionFactory, GroundServicesFactory) {\n var service = {\n createNewLocalReportForFlight: createNewLocalReportForFlight\n };\n /**\r\n * Create a new Local Report For the Selected Flight\r\n * @memberof CrewAssessmentFactory\r\n * @param {number} flightId \r\n * @returns {object} report \r\n */\n\n function createNewLocalReportForFlight(flightId) {\n // load the user\n var user = UserFactory.getUser();\n if (user == null) return null; // check if a report exists for this flight and user\n\n var existingReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId);\n if (existingReport != null) return existingReport; // get a guid for the report\n\n var newReportGuid = ReportGuidFactory.getNextGuid();\n if (newReportGuid == null) return null; // load the cabin report template\n\n var reportTemplateItems = CabinReportTemplateItemFactory.getCabinReportTemplateItemsFromStorage();\n if (reportTemplateItems == null) return null;\n if (reportTemplateItems.length == 0) return null; // load the flight\n\n var flight = FlightFactory.getFlightFromStorage(flightId);\n\n if (flight == null) {\n // if not found, also check the local flights\n var flight = FlightFactory.getLocalFlightFromStorage(flightId); // if still not found, then return null\n\n if (flight == null) return null;\n } // create the new report\n\n\n var newReport = CabinReportLocalEditFactory.getNewReport(); // assign data on the new report\n\n newReport.AuthorId = user.id;\n newReport.AuthorAimsId = user.aimsId;\n newReport.AuthorName = user.name;\n newReport.Created = new Date();\n newReport.FlightAimsId = flight.FlightAimsId;\n newReport.FlightId = flight.FlightId;\n newReport.LastUpdated = new Date();\n newReport.AcType = flight.AcType;\n newReport.AcTailNo = flight.AcTailNo;\n newReport.FlightDate = flight.FlightDate;\n newReport.FlightNo = flight.FlightNo;\n newReport.Departure = flight.Departure;\n newReport.Arrival = flight.Arrival;\n newReport.ScheduledDeparture = flight.ScheduledDeparture;\n newReport.ScheduledDepartureDateUTC = flight.ScheduledDepartureDateUTC;\n newReport.ScheduledDepartureTimeUTC = flight.ScheduledDepartureTimeUTC;\n newReport.ReportGuid = newReportGuid;\n newReport.ReportId = null;\n newReport.Status = 'pending';\n newReport.WaterUpliftSuggestedQuantity = flight.WaterUpliftSuggestedQuantity; // TODO\n\n newReport.VariousIssues = reportTemplateItems; //details from flight (assuming flight contains these fields)\n\n if (flight.DepartureName) {\n newReport.DepartureICAO = flight.DepartureICAO;\n newReport.DepartureCountry = flight.DepartureCountry;\n newReport.DepartureName = flight.DepartureName;\n newReport.ArrivalICAO = flight.ArrivalICAO;\n newReport.ArrivalCountry = flight.ArrivalCountry;\n newReport.ArrivalName = flight.ArrivalName;\n } //pax figures from flight (assuming flight contains these figures)\n\n\n if (flight.BookedY >= 0) {\n newReport.BookedC = flight.BookedC;\n newReport.BookedY = flight.BookedY;\n newReport.BookedInf = flight.BookedInf;\n newReport.BookedPad = flight.BookedPad;\n newReport.BookedChld = flight.BookedChld;\n newReport.ActualC = flight.ActualC;\n newReport.ActualY = flight.ActualY;\n newReport.ActualInf = flight.ActualInf;\n newReport.ActualPad = flight.ActualPad;\n newReport.ActualChld = flight.ActualChld;\n } // fix the CCMS positions\n\n\n for (var i = 0; i < flight.crew.length; i++) {\n if (flight.crew[i].isDHC == false && flight.crew[i].position != 'CP' && flight.crew[i].position != 'FO') {\n var crewPosition = CCMSCrewPositionFactory.createNew();\n crewPosition.CrewId = flight.crew[i].aimsId;\n crewPosition.Initials = flight.crew[i].shortname;\n crewPosition.Name = flight.crew[i].name;\n crewPosition.Position = flight.crew[i].position;\n crewPosition.IsManual = false;\n crewPosition.CrewComments = null;\n crewPosition.HasCrewComments = false;\n crewPosition.needsAdditionalFeedback = false;\n newReport.CCMSCrewPositions.push(crewPosition);\n }\n }\n\n newReport.crew = flight.crew; //new values\n\n newReport.DepartureTimezone = flight.DepartureTimezone;\n newReport.ArrivalTimezone = flight.ArrivalTimezone;\n newReport.CallSign = flight.CallSign;\n newReport.ScheduledArrival = flight.ScheduledArrival;\n newReport.DepartureGate = flight.DepartureGate;\n newReport.Route = flight.Route;\n newReport.DutyDate = flight.DutyDate; //add ground services\n\n newReport.DepartureGroundServices = GroundServicesFactory.getGroundServicesByStation(flight.Departure); //We don't show arrival services any more... \n //newReport.ArrivalGroundServices = GroundServicesFactory.getGroundServicesByStation(flight.Arrival);\n\n newReport.GroomingReports = [];\n newReport.updateTotals(); // return the new report\n\n return newReport;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CabinReportRestoreFactory', CabinReportRestoreFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportRestoreFactory\r\n * @description \r\n * Manage Local Cabin Reports.\r\n * @ngInject\r\n */\n\n function CabinReportRestoreFactory(localStorageMD5Service, FlightFactory, CabinReportLocalEditFactory, IndexedDBService) {\n var IdxType = 'Reports';\n var service = {\n getReportsFromIdx: getReportsFromIdx,\n setReportsToIdx: setReportsToIdx,\n updateReportToIdx: updateReportToIdx,\n addReportToIdx: addReportToIdx,\n deleteReportFromIdx: deleteReportFromIdx,\n clearReportsFromIdx: clearReportsFromIdx,\n getReportsFromLs: getReportsFromLs,\n backUpReports: backUpReports,\n restoreReports: restoreReports\n };\n /**\r\n * Get Reports\r\n * @memberof CabinReportRestoreFactory\r\n * @param {function} callback \r\n */\n\n function getReportsFromIdx(callback) {\n //return GenericService.list(Idx,objCallback);\n IndexedDBService.getAll(IdxType).then(function (results) {\n callback(results);\n });\n }\n\n ;\n /**\r\n * Set Reports\r\n * @memberof CabinReportRestoreFactory\r\n * @param {array} Reports a list of Reports to set to indexedDB\r\n */\n\n function setReportsToIdx(Reports) {\n IndexedDBService.addAll(IdxType, Reports);\n }\n\n ;\n /**\r\n * Update Report to Storage\r\n * @memberof CabinReportRestoreFactory\r\n * @param {object} Report a Report\r\n */\n\n function updateReportToIdx(Report) {\n IndexedDBService.put(IdxType, Report);\n }\n\n ;\n\n function info() {\n IndexedDBService.info(IdxType);\n }\n /**\r\n * Add Report to Storage\r\n * @memberof CabinReportRestoreFactory\r\n * @param {object} Report a Report\r\n */\n\n\n function addReportToIdx(Report) {\n IndexedDBService.add(IdxType, Report);\n }\n\n ;\n /**\r\n * Delete Report from Storage\r\n * @memberof CabinReportRestoreFactory\r\n * @param {number} RerportGuid The unique Identifier of the Report\r\n */\n\n function deleteReportFromIdx(ReportId) {\n IndexedDBService.remove(IdxType, ReportId);\n }\n\n ;\n /**\r\n * Clear Report from Storage\r\n * @memberof CabinReportRestoreFactory\r\n */\n\n function clearReportsFromIdx() {\n IndexedDBService.removeAll(IdxType);\n }\n\n ;\n /**\r\n * Get Cabin Reports from storage\r\n * @memberof CabinReportLocalEditFactory\r\n * @returns {Array} CabinReports\r\n */\n\n function getReportsFromLs() {\n return localStorageMD5Service.get('cabinReportLocalEdits');\n }\n /**\r\n * Get reports from IndexedDB and delete the reports that have been stored\r\n * @memberof CabinReportRestoreFactory\r\n */\n\n\n function getReportsFromIdxDeleteStoredReports(callback) {\n var reportsIdx = [];\n var storedReportsLs = FlightFactory.getFlightsWithStoredReport();\n getReportsFromIdx(function (results) {\n for (var i = 0; i < results.length; i++) {\n var isStored = storedReportsLs.some(function (item) {\n return results[i].FlightId == item.FlightId && item.cabinReportStatusDescr == \"Stored\";\n });\n\n if (isStored) {\n deleteReportFromIdx(results[i].FlightId);\n } else {\n reportsIdx.push(results[i]);\n }\n }\n\n callback(reportsIdx);\n });\n }\n /**\r\n * Back up reports. Gets the reports from localstorage and save them to IndexedDB. \r\n * Steps:\r\n * 1. Clear IndexedDB from reports which have been stored\r\n * 2. Replace the existing reports\r\n * 3. Insert if not existing\r\n * @memberof CabinReportRestoreFactory\r\n */\n\n\n function backUpReports() {\n //1\n //Get reports from indexedDB, check each of them if is existed at the StroredReport list\n getReportsFromIdxDeleteStoredReports(function (reportsIdx) {\n //2\n //Foreach report in the local storage, save to indexedId, if existed need to be replaced \n //get reports from localStorage\n var reportsAll = [];\n reportsAll = getReportsFromLs();\n\n if (reportsAll && reportsAll.length > 0) {\n for (var i = 0; i < reportsAll.length; i++) {\n var reportLs = reportsAll[i];\n var isExisting = reportsIdx.some(function (item) {\n return reportLs.FlightId == item.FlightId;\n });\n\n if (isExisting) {\n //Replace the report\n deleteReportFromIdx(reportLs.FlightId);\n addReportToIdx(reportLs);\n } else {\n //Insert the report\n addReportToIdx(reportLs);\n }\n }\n }\n });\n }\n /**\r\n * Restore reports. Compares the reports from localstorage and from IndexedDB, and it inserts the reports that are missing from local storage. \r\n * Steps:\r\n * 1.\r\n * @memberof CabinReportRestoreFactory\r\n * @returns {array} list of flightNo foreach restored report \r\n */\n\n\n function restoreReports(callback) {\n getReportsFromIdxDeleteStoredReports(function (reportsIdx) {\n var results = [];\n var reportsAll = [];\n reportsAll = getReportsFromLs();\n\n for (var i = 0; i < reportsIdx.length; i++) {\n //Check if exists\n var isExisting = reportsAll.some(function (item) {\n return reportsIdx[i].FlightId == item.FlightId && (reportsIdx[i].Status == \"draft\" || reportsIdx[i].Status == \"completed\");\n });\n\n if (isExisting) {\n //Delete existing reports\n deleteReportFromIdx(reportsIdx[i].FlightId);\n } else {\n //Insert reports that are not existed\n var extendReport = CabinReportLocalEditFactory.fromObject(reportsIdx[i]);\n extendReport.Status = \"draft\";\n extendReport.saveReport();\n FlightFactory.updateFlightFromReport(extendReport); //Then delete from indexed db\n\n deleteReportFromIdx(reportsIdx[i].FlightId);\n results.push(reportsIdx[i].FlightNo);\n }\n }\n\n callback(results);\n });\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CabinReportSendToServerFactory', CabinReportSendToServerFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportSendToServerFactory\r\n * @description \r\n * Transform Cabin Reports in order to send them to the server\r\n * @ngInject\r\n */\n\n function CabinReportSendToServerFactory() {\n /**\r\n * Initialize the CabinReportSendToServer\r\n * @memberof CabinReportSendToServerFactory\r\n */\n function CabinReportSendToServer() {\n this.Created = null;\n this.LastUpdated = null;\n this.FlightAimsId = null;\n this.FlightId = null;\n this.FlightDate = null;\n this.FlightNo = null;\n this.Departure = null;\n this.Arrival = null;\n this.ReportGuid = null;\n this.AuthorCrewId = null;\n this.AuthorCrewAimsId = null;\n this.ActualPassengerC = \"\";\n this.ActualPassengerY = \"\";\n this.CCMSCrewPositions = [];\n this.CrewRemarks = null;\n this.ItemsFoundDescription = null;\n this.ItemsFoundAgent = null;\n this.ItemsFoundSignature = null;\n this.UMNumber = 0;\n this.UMDescription = null;\n this.UMAgent = null;\n this.UMSignature = null;\n this.WaterUpliftSuggestedQuantity = null;\n this.WaterUpliftInitial = null;\n this.WaterUpliftRemarks = null;\n this.BarTrolleys = [];\n this.FirstAidKits = [];\n this.MedicalIncidents = [];\n this.SpecialMealIssues = [];\n this.Supplies = [];\n this.TravelValueSeals = [];\n this.LuggageNumber = 0;\n this.LuggageDescription = null;\n this.TravelValueIncomplete = false;\n this.TravelValueIncompleteRow = null;\n this.TravelValueIncompleteReason = null;\n this.TravelValueRemarks = null;\n this.Remarks = null;\n this.VariousIssues = [];\n this.DepartureGroundServices = [];\n this.ArrivalGroundServices = [];\n this.UpgradedPassengers = [];\n this.ChangedSeats = []; //BoardingTimes\n\n this.BoardingTimesRemarks = null;\n this.FirstPaxTime = null;\n this.LastPaxTime = null;\n this.GroomingReports = [];\n }\n /**\r\n * Initialize the CabinReportSendToServerItem\r\n * @memberof CabinReportSendToServerFactory\r\n */\n\n\n function CabinReportSendToServerItem() {\n this.ReportGuid = null;\n this.TemplateItemId = null;\n this.Value = 0;\n this.Remarks = '';\n this.Photos = new Array();\n }\n\n var service = {\n getCompletedListFromCabinReportLocalEdits: getCompletedListFromCabinReportLocalEdits,\n getReportFromCabinReportLocalEdit: getReportFromCabinReportLocalEdit,\n stripIds: stripIds\n };\n /**\r\n * Transform all cabin local reports in order to be sent to the server\r\n * @memberof CabinReportSendToServerFactory\r\n * @param {Array} cabinReportLocalEdits\r\n * @returns {Array} CabinReportSendToServer \r\n */\n\n function getCompletedListFromCabinReportLocalEdits(cabinReportLocalEdits) {\n var result = [];\n if (cabinReportLocalEdits == null) return result;\n var arrayLength = cabinReportLocalEdits.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (cabinReportLocalEdits[i].Status === 'completed') {\n result.push(getReportFromCabinReportLocalEdit(cabinReportLocalEdits[i]));\n }\n } //Temporary: fix: Ground Services: Used values (true/false) from local storage.\n\n\n var resultChecked = fixUsedValueLS(result);\n return resultChecked;\n } //Temporary: fix - Ground Services - local storage from true/false values. (int Used: 0:false, 1:true, 2:inop) \n\n\n function fixUsedValueLS(cabinReportLocalEdits) {\n for (var i = 0; i < cabinReportLocalEdits.length; i++) {\n if (cabinReportLocalEdits[i].DepartureGroundServices.length > 0) {\n for (var j = 0; j < cabinReportLocalEdits[i].DepartureGroundServices.length; j++) {\n if (cabinReportLocalEdits[i].DepartureGroundServices[j]) {\n if (cabinReportLocalEdits[i].DepartureGroundServices[j].Used === true) {\n cabinReportLocalEdits[i].DepartureGroundServices[j].Used = 1;\n } else if (cabinReportLocalEdits[i].DepartureGroundServices[j].Used === false) {\n cabinReportLocalEdits[i].DepartureGroundServices[j].Used = 0;\n }\n }\n }\n }\n }\n\n return cabinReportLocalEdits;\n }\n /**\r\n * Transform a cabin local reports in order to be sent to the server\r\n * @memberof CabinReportSendToServerFactory\r\n * @param {object} cabinReportLocalEdit\r\n * @returns {object} CabinReportSendToServer \r\n */\n\n\n function getReportFromCabinReportLocalEdit(cabinReportLocalEdit) {\n var result = new CabinReportSendToServer();\n result.Created = cabinReportLocalEdit.Created;\n result.LastUpdated = cabinReportLocalEdit.LastUpdated;\n result.FlightAimsId = cabinReportLocalEdit.FlightAimsId;\n result.FlightId = cabinReportLocalEdit.FlightId;\n result.FlightDate = cabinReportLocalEdit.FlightDate;\n result.FlightNo = cabinReportLocalEdit.FlightNo;\n result.Departure = cabinReportLocalEdit.Departure;\n result.Arrival = cabinReportLocalEdit.Arrival;\n result.ReportGuid = cabinReportLocalEdit.ReportGuid;\n result.AuthorCrewId = cabinReportLocalEdit.AuthorId;\n result.AuthorCrewAimsId = cabinReportLocalEdit.AuthorAimsId;\n result.ActualPassengerC = cabinReportLocalEdit.ActualPassengerC;\n result.ActualPassengerY = cabinReportLocalEdit.ActualPassengerY;\n result.CrewRemarks = cabinReportLocalEdit.CrewRemarks;\n result.ItemsFoundDescription = cabinReportLocalEdit.ItemsFoundDescription;\n result.ItemsFoundAgent = cabinReportLocalEdit.ItemsFoundAgent;\n result.ItemsFoundSignature = cabinReportLocalEdit.ItemsFoundSignature;\n result.UMNumber = cabinReportLocalEdit.UMNumber;\n result.UMDescription = cabinReportLocalEdit.UMDescription;\n result.UMAgent = cabinReportLocalEdit.UMAgent;\n result.UMSignature = cabinReportLocalEdit.UMSignature;\n result.LuggageNumber = cabinReportLocalEdit.LuggageNumber;\n result.LuggageDescription = cabinReportLocalEdit.LuggageDescription;\n result.WaterUpliftSuggestedQuantity = cabinReportLocalEdit.WaterUpliftSuggestedQuantity;\n result.WaterUpliftInitial = cabinReportLocalEdit.WaterUpliftInitial;\n result.WaterUpliftRemarks = cabinReportLocalEdit.WaterUpliftRemarks;\n result.CCMSCrewPositions = stripIds(cabinReportLocalEdit.CCMSCrewPositions);\n result.BarTrolleys = stripIds(cabinReportLocalEdit.BarTrolleys);\n result.FirstAidKits = stripIds(cabinReportLocalEdit.FirstAidKits);\n result.MedicalIncidents = stripIds(cabinReportLocalEdit.MedicalIncidents);\n result.SpecialMealIssues = stripIds(cabinReportLocalEdit.SpecialMealIssues);\n result.Supplies = stripIds(cabinReportLocalEdit.Supplies);\n result.TravelValueSeals = stripIds(cabinReportLocalEdit.TravelValueSeals);\n result.TravelValueIncomplete = cabinReportLocalEdit.TravelValueIncomplete;\n result.TravelValueIncompleteRow = cabinReportLocalEdit.TravelValueIncompleteRow;\n result.TravelValueIncompleteReason = cabinReportLocalEdit.TravelValueIncompleteReason;\n result.TravelValueRemarks = cabinReportLocalEdit.TravelValueRemarks;\n result.Remarks = cabinReportLocalEdit.Remarks;\n result.ArrivalGroundServices = cabinReportLocalEdit.ArrivalGroundServices;\n result.DepartureGroundServices = cabinReportLocalEdit.DepartureGroundServices;\n result.UpgradedPassengers = cabinReportLocalEdit.UpgradedPassengers;\n result.ChangedSeats = cabinReportLocalEdit.ChangedSeats;\n result.IncompleteServices = cabinReportLocalEdit.IncompleteServices;\n result.BoardingTimesRemarks = cabinReportLocalEdit.BoardingTimesRemarks;\n result.DisembarkationTimeRemarks = cabinReportLocalEdit.DisembarkationTimesRemarks;\n\n if (cabinReportLocalEdit.FirstPaxTime) {\n result.FirstPaxTime = cabinReportLocalEdit.FirstPaxTime;\n }\n\n if (cabinReportLocalEdit.LastPaxTime) {\n result.LastPaxTime = cabinReportLocalEdit.LastPaxTime;\n }\n\n if (cabinReportLocalEdit.FirstPaxDisembarkationTime) {\n result.FirstPaxDisembarkationTime = cabinReportLocalEdit.FirstPaxDisembarkationTime;\n }\n\n if (cabinReportLocalEdit.LastPaxDisembarkationTime) {\n result.LastPaxDisembarkationTime = cabinReportLocalEdit.LastPaxDisembarkationTime;\n }\n\n result.VariousIssues = [];\n var itemCount = cabinReportLocalEdit.VariousIssues.length;\n\n for (var i = 0; i < itemCount; i++) {\n var newItem = new CabinReportSendToServerItem();\n newItem.ReportGuid = cabinReportLocalEdit.ReportGuid;\n newItem.TemplateItemId = cabinReportLocalEdit.VariousIssues[i].Id;\n newItem.Value = cabinReportLocalEdit.VariousIssues[i].ItemHasValue ? 1 : 0;\n\n if (newItem.Value == 1) {\n newItem.Remarks = cabinReportLocalEdit.VariousIssues[i].ItemValue;\n newItem.Photos = stripIds(cabinReportLocalEdit.VariousIssues[i].Photos);\n }\n\n result.VariousIssues.push(newItem);\n }\n\n result.GroomingReports = cabinReportLocalEdit.GroomingReports;\n return result;\n }\n /**\r\n * Strip Ids of selected input\r\n * @memberof CabinReportSendToServerFactory\r\n * @param {array} inputArray\r\n * @returns {object} stripedInputArray \r\n */\n\n\n function stripIds(inputArray) {\n for (var i = 0; i < inputArray.length; i++) {\n delete inputArray[i].Id;\n }\n\n return inputArray;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CabinReportSyncResultFactory', CabinReportSyncResultFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportSyncResultFactory\r\n * @description \r\n * Manage Cabin Report Sync Results\r\n * @ngInject\r\n */\n\n function CabinReportSyncResultFactory(GenericService) {\n /**\r\n * Initialize the CabinReportSyncResult\r\n * @memberof CabinReportSyncResultFactory\r\n */\n function CabinReportSyncResult() {\n this.reportGuid = null;\n this.message = null;\n this.success = null;\n this.FlightAimsId = null;\n this.FlightId = null;\n this.ScheduledDepartureDateUTC = null;\n this.FlightNo = null;\n this.Departure = null;\n this.Arrival = null;\n this.ScheduledDepartureTimeUTC = null;\n this.AcTailNo = null;\n this.Result = null;\n this.getRoute = getRoute;\n }\n /**\r\n * Get Report Route\r\n * @memberof CabinReportSyncResultFactory\r\n * @return {string} route\r\n */\n\n\n function getRoute() {\n if (this.Departure == null && this.Arrival == null) return '-null-';else return (this.Departure || '?') + '-' + (this.Arrival || '?');\n }\n\n var objType = 'cabinReportSyncResults';\n var objCallback = CabinReportSyncResult;\n var service = {\n getSyncResult: getSyncResult,\n getCabinReportSyncResultsFromStorage: getCabinReportSyncResultsFromStorage,\n setCabinReportSyncResultsToStorage: setCabinReportSyncResultsToStorage,\n getSuccesses: getSuccesses,\n getFailures: getFailures,\n fromObjectList: fromObjectList\n };\n /**\r\n * Extend an array of Objects from the default CabinReportSyncResult Object\r\n * @memberof CabinReportSyncResultFactory\r\n * @param {Array} objList an Array Of Cabin Report Sync Results\r\n * @returns {Array} CabinReportSyncResults\r\n */\n\n function fromObjectList(objList) {\n return GenericService.fromObjectList(objList, objCallback);\n }\n /**\r\n * Get Sync Result from given list\r\n * @memberof CabinReportSyncResultFactory\r\n * @param {Array} syncResults an Array Of Cabin Report Sync Results\r\n * @param {string} reportGuid The report's Guid\r\n * @returns {object} CabinReportSyncResult\r\n */\n\n\n function getSyncResult(syncResults, reportGuid) {\n if (syncResults == null) return null;\n var result = null;\n var arrayLength = syncResults.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (syncResults[i].reportGuid == reportGuid) {\n result = syncResults[i];\n break;\n }\n }\n\n return result;\n }\n\n ;\n /**\r\n * Get Sync Results\r\n * @memberof CabinReportSyncResultFactory\r\n * @returns {array} CabinReportSyncResults\r\n */\n\n function getCabinReportSyncResultsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Set Sync Results\r\n * @memberof CabinReportSyncResultFactory\r\n * @param {Array} syncResults an Array Of Cabin Report Sync Results\r\n */\n\n\n function setCabinReportSyncResultsToStorage(cabinReportSyncResults) {\n GenericService.saveAll(cabinReportSyncResults, objType, objCallback);\n }\n /**\r\n * Get Successfull Sync Results from given syncResult\r\n * @memberof CabinReportSyncResultFactory\r\n * @returns {array} successes\r\n */\n\n\n function getSuccesses(syncResults) {\n var result = 0;\n\n for (var i = 0; i < syncResults.length; i++) {\n if (syncResults[i].success == true) {\n result = result + 1;\n }\n }\n\n return result;\n }\n /**\r\n * Get Failed Sync Results from given syncResults\r\n * @memberof CabinReportSyncResultFactory\r\n * @returns {array} failures\r\n */\n\n\n function getFailures(syncResults) {\n var result = 0;\n\n for (var i = 0; i < syncResults.length; i++) {\n if (syncResults[i].success == false) {\n result = result + 1;\n }\n }\n\n return result;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CabinReportTemplateItemFactory', CabinReportTemplateItemFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportTemplateItemFactory\r\n * @description \r\n * Manage Cabin Report Template Item.\r\n * @ngInject\r\n */\n\n function CabinReportTemplateItemFactory(GenericService) {\n /**\r\n * Initialize the CabinReportTemplateItem\r\n * @memberof CabinReportTemplateItemFactory\r\n */\n function CabinReportTemplateItem() {\n this.Id = null;\n this.Hint = null;\n this.Label = null;\n this.OrderNo = null;\n this.CategoryLabel = null;\n this.PresetComments = null;\n this.Photos = new Array();\n this.GetId = GetId;\n }\n\n var objType = 'cabinReportTemplateItems';\n var objCallback = CabinReportTemplateItem;\n var service = {\n getCabinReportTemplateItemsFromStorage: getCabinReportTemplateItemsFromStorage,\n setCabinReportTemplateItemsToStorage: setCabinReportTemplateItemsToStorage,\n newItem: newItem\n };\n /**\r\n * Overide default get Id\r\n * @memberof CabinReportTemplateItemFactory\r\n * @returns {number} Id \r\n */\n\n function GetId() {\n return this.Id;\n }\n /**\r\n * Get Cabin Report Template Items\r\n * @memberof CabinReportTemplateItemFactory\r\n * @returns {Array} CabinReportTemplateItems \r\n */\n\n\n function getCabinReportTemplateItemsFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Save Cabin Report Template Items to storage\r\n * @memberof CabinReportTemplateItemFactory\r\n * @param {Array} CabinReportTemplateItems A list of Cabin Report Template Items\r\n */\n\n\n function setCabinReportTemplateItemsToStorage(cabinReportTemplateItems) {\n GenericService.saveAll(cabinReportTemplateItems, objType, objCallback);\n }\n /**\r\n * Create a new Cabin Report Template Item \r\n * @memberof CabinReportTemplateItemFactory\r\n * @return {object} CabinReportTemplateItem\r\n */\n\n\n function newItem() {\n return GenericService.constructor(objCallback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('ReportCtrl', ReportCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ReportCtrl\r\n * @description \r\n * Manages the Report View\r\n * @ngInject\r\n */\n\n function ReportCtrl($scope, $log, $uibModal, $timeout, $routeParams, UserFactory, FlightFactory, CabinReportLocalEditFactory, CabinReportLocalEditCreatorFactory, $location, SettingsMain, WaterUpliftActionFactory, enableWaterUpliftReporting, BarTrolleyFactory, FirstAidKitFactory, MedicalIncidentFactory, SpecialMealIssueFactory, IncompleteServicesIssueFactory, SupplyFactory, TravelValueSealFactory, CCMSCrewPositionFactory, CCMSFactory, ReportGuidFactory, TravelValueIncompleteReasonFactory, LogService, CrewAssessmentFactory, $route, InfoAPIService, customerIncidentQuestionIds, PaxInfoFactory, GroomingCategoriesFactory) {\n // get the report id\n var reportId = $routeParams.reportId;\n var _report = null;\n var user = UserFactory.getUser();\n var editingPage = SettingsMain.getEditingPage();\n $scope.IsCustomerIncident = IsCustomerIncident;\n $scope.enableWaterUpliftReporting = enableWaterUpliftReporting;\n\n function IsCustomerIncident(id) {\n return customerIncidentQuestionIds.includes(id);\n }\n\n var groomingCategories = GroomingCategoriesFactory.getGroomingCategories();\n $scope.hasGroomingCategories = groomingCategories.length > 0;\n\n $scope.discard = function () {\n if (_report == null) {\n _report = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId);\n }\n\n var guid = _report.ReportGuid;\n var status = _report.Status; // delete the temp report\n\n CabinReportLocalEditFactory.deleteTempReport(); //reuse guid if this was a new report\n\n if (status == 'pending') ReportGuidFactory.restoreGuid(_report.ReportGuid); // new / edit existing / load from temp\n\n if (reportId.startsWith('new:')) {\n var flightId = $routeParams.flightId; // create a new report\n\n var newLocalReport = CabinReportLocalEditCreatorFactory.createNewLocalReportForFlight(flightId);\n\n if (newLocalReport == null) {\n bootbox.alert(\"

Attention

Unable to create a new log!
Available pool of resources has been depleted and you need to synchronize with the server to renew it.\", function () {\n $location.path(\"/\");\n $scope.$apply();\n });\n } else {\n // load the new report\n _report = newLocalReport;\n }\n } else if (reportId == 'temp') {\n // load the report from the temp place\n _report = CabinReportLocalEditFactory.getCabinReportLocalEditFromTemp();\n\n if (_report == null) {\n // since we could not load the temp report, delete it\n CabinReportLocalEditFactory.deleteTempReport();\n bootbox.alert(\"

Warning

Unable to load temporary log.
No temporary log found in this device or the report was corrupted\", function () {\n $location.path(\"/\");\n $scope.$apply();\n });\n }\n } else {\n // load the report\n _report = CabinReportLocalEditFactory.getCabinReportLocalEdit(reportId);\n\n if (_report == null) {\n bootbox.alert(\"

Warning

Unable to load the requested log.
This entry does not exist in this device, our its data are corrupted and the entry is unusable.\", function () {\n $location.path(\"/\");\n $scope.$apply();\n });\n }\n }\n\n $scope.report = _report;\n infoSaveOperation('discard');\n };\n\n $scope.state = 'report';\n $scope.logged_user_info = user.aimsId + ' - ' + user.name;\n $scope.isSecure = UserFactory.isSecure(); // new / edit existing / load from temp\n\n if (reportId.startsWith('new:')) {\n var flightId = $routeParams.flightId; // create a new report\n\n var newLocalReport = CabinReportLocalEditCreatorFactory.createNewLocalReportForFlight(flightId);\n\n if (newLocalReport == null) {\n bootbox.alert(\"

Attention

Unable to create a new log!
Available pool of resources has been depleted and you need to synchronize with the server to renew it.\", function () {\n $location.path(\"/\");\n $scope.$apply();\n });\n return;\n } else {\n // load the new report\n _report = newLocalReport;\n }\n } else if (reportId == 'temp') {\n // load the report from the temp place\n _report = CabinReportLocalEditFactory.getCabinReportLocalEditFromTemp();\n\n if (_report == null) {\n // since we could not load the temp report, delete it\n CabinReportLocalEditFactory.deleteTempReport();\n bootbox.alert(\"

Warning

Unable to load temporary log.
No temporary log found in this device or the report was corrupted\", function () {\n $location.path(\"/\");\n $scope.$apply();\n });\n return;\n }\n } else {\n // load the report\n _report = CabinReportLocalEditFactory.getCabinReportLocalEdit(reportId);\n\n if (_report == null) {\n bootbox.alert(\"

Warning

Unable to load the requested log.
This entry does not exist in this device, our its data are corrupted and the entry is unusable.\", function () {\n $location.path(\"/\");\n $scope.$apply();\n });\n return;\n }\n }\n\n $scope.countDHC = 0;\n if (_report.crew) $scope.countDHC = _report.crew.filter(function (item) {\n return item.isDHC == true;\n }).length; //Additional feedback\n\n if (_report.crew) {\n var crewNeedsAdditionalFeedback = [];\n\n var crewMemberNeedsAdditionalFeedback = _report.crew.filter(function (x) {\n return x.needsAdditionalFeedback;\n });\n\n crewNeedsAdditionalFeedback.push(crewMemberNeedsAdditionalFeedback);\n\n if (crewNeedsAdditionalFeedback.length > 0) {\n var crewNeedsAdditionalFeedbackFlatten = crewNeedsAdditionalFeedback.flat();\n\n for (var i = 0; i < crewNeedsAdditionalFeedbackFlatten.length; i++) {\n _report.CCMSCrewPositions.find(function (x) {\n return x.CrewId == crewNeedsAdditionalFeedbackFlatten[i].aimsId;\n }).needsAdditionalFeedback = true;\n _report.CCMSCrewPositions.find(function (x) {\n return x.CrewId == crewNeedsAdditionalFeedbackFlatten[i].aimsId;\n }).AdditionalFeedback = crewNeedsAdditionalFeedbackFlatten[i].AdditionalFeedback;\n _report.CCMSCrewPositions.find(function (x) {\n return x.CrewId == crewNeedsAdditionalFeedbackFlatten[i].aimsId;\n }).AdditionalFeedbackId = crewNeedsAdditionalFeedbackFlatten[i].AdditionalFeedback.Id;\n _report.CCMSCrewPositions.find(function (x) {\n return x.CrewId == crewNeedsAdditionalFeedbackFlatten[i].aimsId;\n }).FeedbackAuthorName = crewNeedsAdditionalFeedbackFlatten[i].AdditionalFeedback.FeedbackAuthorName;\n _report.CCMSCrewPositions.find(function (x) {\n return x.CrewId == crewNeedsAdditionalFeedbackFlatten[i].aimsId;\n }).Route = _report.Route;\n }\n }\n } // update totals and set to scope\n\n\n _report.updateTotals();\n\n $scope.report = _report;\n $scope.infosaveaction = false; // save the report to a temp place\n\n if (_report.Status != 'synched') _report.saveReportAsTemp(); // set editing page to report\n\n SettingsMain.setEditingPage('report');\n\n if (_report && _report.ScheduledArrival) {\n var nowTimeStamp = moment.utc().valueOf();\n var schedullDepartureTimestamp = new Date(_report.ScheduledArrival).getTime();\n $scope.isFuture = nowTimeStamp < schedullDepartureTimestamp;\n }\n\n $scope.showCompleted = showCompleted;\n $scope.showAll = showAll;\n $scope.compressedMode = false;\n\n function showCompleted() {\n if (!$scope.report.BarTrolleys || $scope.report.BarTrolleys.length == 0) $scope.panels.bars.visible = false;\n if (!$scope.report.MedicalIncidents || !(_report.FirstAidKits.length > 0 || _report.MedicalIncidents.length > 0)) $scope.panels.medical.visible = false;\n if (!$scope.report.ItemsFoundSectionHasValue) $scope.panels.security.visible = false;\n if (!$scope.report.SpecialMealIssues || $scope.report.SpecialMealIssues.length == 0) $scope.panels.special.visible = false;\n if (!$scope.report.Supplies || $scope.report.Supplies.length == 0) $scope.panels.supplies.visible = false;\n if (!$scope.report.TravelValueSeals || !(_report.TravelValueSeals.length > 0 || _report.TravelValueIncomplete || _report.TravelValueRemarks != null && _report.TravelValueRemarks != '')) $scope.panels.travel.visible = false;\n if (!$scope.report.UMSectionHasValue) $scope.panels.um.visible = false;\n if ($scope.report.ActiveVariousIssues == 0) $scope.panels.various.visible = false;\n if (!$scope.report.WaterSectionHasValue) $scope.panels.water.visible = false;\n if (!($scope.report.UpgradedPassengers.length > 0)) $scope.panels.upgd.visible = false;\n if (!($scope.report.ChangedSeats.length > 0)) $scope.panels.changedSeats.visible = false;\n if (!($scope.report.IncompleteServices.length > 0)) $scope.panels.incompleteServices.visible = false;\n if (!$scope.report.BoardingTimes || _report.BoardingTimesRemarks != null && _report.BoardingTimesRemarks != '') $scope.panels.travel.visible = false;\n if (!$scope.report.LuggageSectionHasValue) $scope.panels.luggage.visible = false;\n $scope.panels.leg.open = !$scope.panels.leg.open;\n $scope.compressedMode = true;\n }\n\n function showAll() {\n $scope.panels.bars.visible = true;\n $scope.panels.medical.visible = true;\n $scope.panels.security.visible = true;\n $scope.panels.special.visible = true;\n $scope.panels.supplies.visible = true;\n $scope.panels.travel.visible = true;\n $scope.panels.various.visible = true;\n $scope.panels.water.visible = true;\n $scope.panels.groundServices.visible = true;\n $scope.panels.upgd.visible = true;\n $scope.panels.changedSeats.visible = true;\n $scope.panels.incompleteServices.visible = true;\n $scope.panels.boardingTimes.visible = true;\n $scope.panels.disembarkationTimes.visible = true;\n $scope.panels.luggage.visible = true;\n $scope.panels.leg.open = !$scope.panels.leg.open;\n $scope.compressedMode = false;\n }\n\n $scope.panels = {\n showOnlyOne: true,\n leg: {\n visible: true,\n open: true,\n cssClass: function cssClass() {\n return _report.IsValid ? 'panel-green' : 'panel-orange';\n }\n },\n info: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n return 'panel-green';\n }\n },\n ccms: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n return !_report.CCMSCrewPositionsIsValid || _report.CCMSCrewPositions.length == 0 ? 'panel-orange' : 'panel-green';\n }\n },\n bars: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (!_report.BarTrolleysIsValid) return 'panel-orange';else if (_report.BarTrolleys.length > 0) return 'panel-green';else return 'panel-default';\n }\n },\n medical: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (!_report.FirstAidKitsIsValid || !_report.MedicalIncidentsIsValid) return 'panel-orange';else if (_report.FirstAidKits.length > 0 || _report.MedicalIncidents.length > 0) return 'panel-green';else return 'panel-default';\n }\n },\n security: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (!_report.ItemsFoundSectionIsValid) return 'panel-orange';else if (_report.ItemsFoundSectionHasValue) return 'panel-green';else return 'panel-default';\n }\n },\n special: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (!_report.SpecialMealIssuesIsValid) return 'panel-orange';else if (_report.SpecialMealIssues.length > 0) return 'panel-green';else return 'panel-default';\n }\n },\n supplies: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (!_report.SuppliesIsValid) return 'panel-orange';else if (_report.Supplies.length > 0) return 'panel-green';else return 'panel-default';\n }\n },\n travel: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (!_report.TravelValueSealsIsValid || !_report.TravelValueIncompleteIsValid)\n /*!report.CashValuesIsValid)*/\n return 'panel-orange';else if (_report.TravelValueSeals.length > 0 || _report.TravelValueIncomplete || _report.TravelValueRemarks != null && _report.TravelValueRemarks != '') return 'panel-green';else return 'panel-default';\n }\n },\n um: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (!_report.UMSectionIsValid) return 'panel-orange';else if (_report.UMSectionHasValue) return 'panel-green';else return 'panel-default';\n }\n },\n various: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (_report.WarningVariousIssues > 0) return 'panel-orange';else if (_report.ActiveVariousIssues > 0) return 'panel-green';else return 'panel-default';\n }\n },\n water: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (!_report.WaterSectionIsValid) return 'panel-orange';else if (_report.WaterSectionHasValue) return 'panel-green';else return 'panel-default';\n }\n },\n groundServices: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (_report.GroundServicesSectionHasValue) return 'panel-green';else return 'panel-default';\n }\n },\n upgd: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (_report.UpgradedPassengers.length > 0) return 'panel-green';else return 'panel-default';\n }\n },\n changedSeats: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (_report.ChangedSeats.length > 0) return 'panel-green';else return 'panel-default';\n }\n },\n incompleteServices: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (_report.IncompleteServices.length > 0) return 'panel-green';else return 'panel-default';\n }\n },\n boardingTimes: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (_report.FirstPaxTime && _report.LastPaxTime) return 'panel-green';else return 'panel-default';\n }\n },\n disembarkationTimes: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (_report.FirstPaxDisembarkationTime && _report.LastPaxDisembarkationTime) return 'panel-green';else return 'panel-default';\n }\n },\n luggage: {\n visible: true,\n open: false,\n cssClass: function cssClass() {\n if (_report.LuggageNumber > 0) return 'panel-green';else return 'panel-default';\n }\n }\n };\n\n $scope.panelClicked = function (e) {\n var q = $(e.currentTarget);\n if (q.hasClass('panel-sector')) q = q.find('textarea');else q = q.parent('.panel-sector').find('textarea');\n q.each(function (index, item) {\n autoAdjustTextarea(item);\n });\n };\n\n var flight = FlightFactory.getFlightFromStorage(_report.FlightId);\n\n if (flight == null) {\n flight = FlightFactory.getLocalFlightFromStorage(_report.FlightId);\n }\n\n if (flight == null) {\n handleIfReport(_report);\n SettingsMain.setEditingPage(null);\n $location.path(\"/\");\n }\n\n if (flight != null) {\n $scope.flight = flight;\n var dateObj = new Date(flight.FlightDate);\n $scope.waterSectionRequired = dateObj.getDate() == 1 || dateObj.getDate() == 15;\n }\n\n if (flight == null) {\n handleIfReport(_report);\n SettingsMain.setEditingPage(null);\n $location.path(\"/\");\n }\n\n if (flight != null) {\n $scope.flight = flight;\n var dateObj = new Date(flight.FlightDate);\n $scope.waterSectionRequired = dateObj.getDate() == 1 || dateObj.getDate() == 15;\n }\n\n $scope.sendCustomerIncident = sendCustomerIncident;\n /**\r\n * Send application Customer Incident information\r\n * @memberof ReportCtrl\r\n */\n\n function sendCustomerIncident(description, label, photos) {\n var image = photos.length > 0 ? photos[0].PhotoData : null;\n var flightDate = new Date(flight.FlightDate);\n var flightDescription = flight.FlightNo + \" \" + flight.Departure + \"-\" + flight.Arrival + \" \" + (flightDate.getUTCDate() > 10 ? flightDate.getUTCDate() : \"0\" + flightDate.getUTCDate()) + \"-\" + (flightDate.getUTCMonth() > 9 ? flightDate.getUTCMonth() + 1 : \"0\" + (flightDate.getUTCMonth() + 1)) + \"-\" + flightDate.getUTCFullYear();\n var _customerIncident = {\n flightDescription: flightDescription,\n question: label,\n description: description,\n image: image\n };\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgCustomerIncidentSend.html',\n controller: 'CustomerModalCtrl',\n size: 'md',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n customerIncident: function customerIncident() {\n return _customerIncident;\n }\n }\n });\n } //Clear Fields Functionality\n\n\n $scope.clearItemsFoundDescription = clearItemsFoundDescription;\n $scope.clearItemsFoundAgent = clearItemsFoundAgent;\n $scope.clearItemsFoundSignature = clearItemsFoundSignature;\n $scope.clearUMDescription = clearUMDescription;\n $scope.clearUMAgent = clearUMAgent;\n $scope.clearUMSignature = clearUMSignature;\n $scope.clearWaterRemarks = clearWaterRemarks;\n $scope.clearTravelValueRemarks = clearTravelValueRemarks;\n $scope.clearBoardingTimesRemarks = clearBoardingTimesRemarks;\n $scope.clearDisembarkationTimesRemarks = clearDisembarkationTimesRemarks;\n $scope.clearRemarks = clearRemarks;\n $scope.clearCrewRemarks = clearCrewRemarks;\n $scope.clearVariousItemRemarks = clearVariousItemRemarks;\n $scope.clearBarSealsPhotoRemarks = clearBarSealsPhotoRemarks;\n $scope.clearLuggageDescription = clearLuggageDescription;\n $scope.reportItemValueChanged = reportItemValueChanged;\n $scope.cancelClicked = cancelClicked;\n $scope.saveClicked = saveClicked;\n $scope.saveDraftClicked = saveDraftClicked;\n $scope.deleteReportClicked = deleteReportClicked; //update report when a report item is changed\n\n $scope.reportChanged = reportChanged; // Incomplete Travel\n // Get list of reasons\n\n $scope.reportTravelValueIncompleteReasons = TravelValueIncompleteReasonFactory.getReasonsFromStorage();\n $scope.plusTravelValueIncompleteRow = plusTravelValueIncompleteRow;\n $scope.minusTravelValueIncompleteRow = minusTravelValueIncompleteRow;\n $scope.reportTravelIncompleteChanged = reportTravelIncompleteChanged; //UMnumber\n\n $scope.plusUMNumber = plusUMNumber;\n $scope.minusUMNumber = minusUMNumber;\n $scope.clearUMNumber = clearUMNumber;\n $scope.waterUpliftActions = WaterUpliftActionFactory.getWaterUpliftActionsFromStorageAsStrings(); //copy positions from previous leg, to minimize input\n //normally, ac performs several legs in a row with the same crew, each at the same position on all legs\n\n $scope.copyCcmsPositions = copyCcmsPositions; // List of ccms position of this A/C\n\n $scope.reportCCMSPositions = reportCCMSPositions; //Modals\n // Bars Trolleys\n\n $scope.addNewBarTrolley = addNewBarTrolley;\n $scope.editBarTrolley = editBarTrolley;\n $scope.deleteBarTrolley = deleteBarTrolley; // Luggage Number\n\n $scope.plusLuggageNumber = plusLuggageNumber;\n $scope.minusLuggageNumber = minusLuggageNumber;\n $scope.clearLuggageNumber = clearLuggageNumber; // CCMS\n\n $scope.addNewCCMSCrewPosition = addNewCCMSCrewPosition;\n $scope.editCCMSCrewPosition = editCCMSCrewPosition;\n $scope.deleteCCMSCrewPosition = deleteCCMSCrewPosition;\n $scope.user = UserFactory.getUser();\n $scope.showFeedback = [];\n\n $scope.toggleAdditionalFeedback = function ($index) {\n $scope.showFeedback[$index] = !$scope.showFeedback[$index];\n }; //CCMS: Show(toggle) CrewComments\n\n\n $scope.showCrewComments = function (item) {\n if (item.HasCrewComments == true && !item.CrewComments) {\n item.HasCrewComments = false;\n } //Clear comments\n else if (item.HasCrewComments == true) {\n bootbox.dialog({\n message: \"Please confirm that you wish to clear the comments\",\n title: \"Attention\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n ok: {\n label: \"Ok\",\n className: \"btn-warning\",\n callback: function callback() {\n $timeout(function () {\n item.CrewComments = null;\n item.HasCrewComments = false;\n });\n return true;\n }\n }\n }\n });\n } else {\n item.HasCrewComments = true;\n }\n }; //Additional Feedback: Show(toggle) Crew Comments\n\n\n $scope.showAdditionalFeedback = function (item) {\n if (item.HasAdditionalFeedbackComments == true && !item.CrewComments) {\n item.HasAdditionalFeedbackComments = false;\n } //Clear comments\n else if (item.HasAdditionalFeedbackComments == true) {\n bootbox.dialog({\n message: \"Please confirm that you wish to clear the comments\",\n title: \"Attention\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n ok: {\n label: \"Ok\",\n className: \"btn-warning\",\n callback: function callback() {\n $timeout(function () {\n item.CrewComments = null;\n item.HasAdditionalFeedbackComments = false;\n });\n return true;\n }\n }\n }\n });\n } else {\n item.HasAdditionalFeedbackComments = true;\n }\n }; // Flight Detail\n\n\n $scope.openFlightDetailModal = openFlightDetailModal; // First Aid Kits\n\n $scope.addNewFirstAidKit = addNewFirstAidKit;\n $scope.editFirstAidKit = editFirstAidKit;\n $scope.deleteFirstAidKit = deleteFirstAidKit; // Medical Incidents\n\n $scope.addNewMedicalIncident = addNewMedicalIncident;\n $scope.editMedicalIncident = editMedicalIncident;\n $scope.deleteMedicalIncident = deleteMedicalIncident; // Special Meals\n\n $scope.addNewSpecialMealIssue = addNewSpecialMealIssue;\n $scope.editSpecialMealIssue = editSpecialMealIssue;\n $scope.deleteSpecialMealIssue = deleteSpecialMealIssue; // Supplies\n\n $scope.addNewSupply = addNewSupply;\n $scope.editSupply = editSupply;\n $scope.deleteSupply = deleteSupply; //UPGDs\n\n $scope.addNewUPGD = addNewUPGD;\n $scope.editUPGD = editUPGD;\n $scope.deleteUPGD = deleteUPGD; //Changed seats\n\n $scope.addNewChangedSeat = addNewChangedSeat;\n $scope.editChangedSeat = editChangedSeat;\n $scope.deleteChangedSeat = deleteChangedSeat; // Travel value seal \n\n $scope.addNewTravelValueSeal = addNewTravelValueSeal;\n $scope.editTravelValueSeal = editTravelValueSeal;\n $scope.deleteTravelValueSeal = deleteTravelValueSeal; // Incomplete in-flight Services\n\n $scope.addIncompleteService = addIncompleteService;\n $scope.editIncompleteService = editIncompleteService;\n $scope.deleteIncompleteService = deleteIncompleteService; // Attatch Photo\n\n $scope.attachPhotoOnVariousItem = attachPhotoOnVariousItem;\n $scope.attachPhotoOnBarTrolley = attachPhotoOnBarTrolley;\n $scope.addNewEMKFirstAidKit = addNewEMKFirstAidKit; // Additional Feedback\n\n $scope.addAdditionalFeedback = addAdditionalFeedback; //Clear functions \n\n /**\r\n * Clear Selected Field\r\n * @memberof ReportCtrl\r\n * @param {object} target the object whose field we want to clear\r\n * @param {string} fieldName the field Name to clear\r\n */\n\n function clearField(target, fieldName) {\n if (target[fieldName] == undefined || target[fieldName] == null || target[fieldName] == '') return false;\n bootbox.dialog({\n message: \"Please confirm that you wish to clear this field\",\n title: \"Attention\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n ok: {\n label: \"Ok\",\n className: \"btn-warning\",\n callback: function callback() {\n target[fieldName] = null;\n $timeout($scope.reportItemValueChanged); //TODO REMOVE COMMENT DANGEROUS $SCOPE $APPLY\n //$scope.$apply();\n\n return true;\n }\n }\n }\n });\n }\n /**\r\n * Clear itemsFoundDescription\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearItemsFoundDescription() {\n clearField($scope.report, \"ItemsFoundDescription\");\n }\n /**\r\n * Clear itemsFoundAgent\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearItemsFoundAgent() {\n clearField($scope.report, \"ItemsFoundAgent\");\n }\n /**\r\n * Clear itemsFoundSignature\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearItemsFoundSignature() {\n clearField($scope.report, \"ItemsFoundSignature\");\n }\n /**\r\n * Clear UMDescription\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearUMDescription() {\n clearField($scope.report, \"UMDescription\");\n }\n /**\r\n * Clear UMAgent\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearUMAgent() {\n clearField($scope.report, \"UMAgent\");\n }\n /**\r\n * Clear UMSignature\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearUMSignature() {\n clearField($scope.report, \"UMSignature\");\n }\n /**\r\n * Clear LuggageDescription\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearLuggageDescription() {\n clearField($scope.report, \"LuggageDescription\");\n }\n /**\r\n * Clear WaterRemarks\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearWaterRemarks() {\n clearField($scope.report, \"WaterUpliftRemarks\");\n }\n /**\r\n * Clear Travel Value Remarks\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearTravelValueRemarks() {\n clearField($scope.report, \"TravelValueRemarks\");\n }\n /**\r\n * Clear boarding times Remarks\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearBoardingTimesRemarks() {\n clearField($scope.report, \"BoardingTimesRemarks\");\n }\n /**\r\n * Clear disembarkation times Remarks\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearDisembarkationTimesRemarks() {\n clearField($scope.report, \"DisembarkationTimesRemarks\");\n }\n /**\r\n * Clear Remarks\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearRemarks() {\n clearField($scope.report, \"Remarks\");\n }\n /**\r\n * Clear Crew Remarks\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearCrewRemarks() {\n clearField($scope.report, \"CrewRemarks\");\n }\n /**\r\n * Clear Various Item Remarks\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearVariousItemRemarks(item) {\n if (item != null) {\n clearField(item, \"ItemValue\");\n }\n }\n /**\r\n * Clear Various Item Remarks\r\n * @memberof ReportCtrl\r\n */\n\n\n function clearBarSealsPhotoRemarks(item) {\n if (item != null) {\n clearField(item, \"PhotoRemarks\");\n }\n }\n /**\r\n * When the user types a value into a report item updates totals of the report\r\n * @memberof ReportCtrl\r\n */\n\n\n function reportItemValueChanged() {\n // update the report totals\n _report.updateTotals();\n }\n /**\r\n * Go to calendar and reset report\r\n * @memberof ReportCtrl\r\n */\n\n\n function cancelClicked() {\n //store report details\n var guid = _report.ReportGuid;\n var status = _report.Status; // delete the temp report\n\n CabinReportLocalEditFactory.deleteTempReport(); //reuse guid if this was a new report\n\n if (status == 'pending') ReportGuidFactory.restoreGuid(_report.ReportGuid); // set editing page to none\n\n SettingsMain.setEditingPage(null); // go to dashboard\n\n $location.path(\"/\");\n }\n /**\r\n * Show information about the save action\r\n * @memberof ReportCtrl\r\n * @param {string} state The action of the save completed or draft or discard\r\n */\n\n\n function infoSaveOperation(state) {\n if (state == 'completed') {\n $scope.infosaveactiontype = state;\n $scope.infosaveaction = true;\n } else if (state == 'draft') {\n $scope.infosaveactiontype = state;\n $scope.infosaveaction = true;\n } else if (state == 'discard') {\n $scope.infosaveactiontype = state;\n $scope.infosaveaction = true;\n }\n\n $timeout(function () {\n $scope.infosaveaction = false;\n }, 5000);\n }\n /**\r\n * Save Completed and Go to calendar\r\n * @memberof ReportCtrl\r\n */\n\n\n function saveClicked() {\n $scope.groomingReports = GroomingCategoriesFactory.collectGroomingReports($scope.groomingReportsByCrew);\n GroomingCategoriesFactory.saveGroomingReports($scope.groomingReportsByCrew);\n _report.GroomingReports = $scope.groomingReports; // save the report\n\n _report.Status = 'completed';\n\n _report.saveReport();\n\n FlightFactory.updateFlightFromReport(_report); // delete the temp report\n\n CabinReportLocalEditFactory.deleteTempReport();\n CrewAssessmentFactory.updateCrewMembers(_report.CCMSCrewPositions, _report.Route, _report.DutyDate); // set editing page to none\n\n SettingsMain.setEditingPage(null);\n infoSaveOperation(_report.Status); // go to flight info\n\n $location.path('/flightinfo/' + _report.FlightId);\n }\n /**\r\n * Save Draft\r\n * @memberof ReportCtrl\r\n */\n\n\n function saveDraftClicked() {\n // save the report\n _report.Status = 'draft';\n\n _report.saveReport();\n\n FlightFactory.updateFlightFromReport(_report);\n CrewAssessmentFactory.updateCrewMembers(_report.CCMSCrewPositions, _report.Route, _report.DutyDate); // delete the temp report\n\n CabinReportLocalEditFactory.deleteTempReport(); // set editing page to none\n\n SettingsMain.setEditingPage(null);\n infoSaveOperation(_report.Status); // go to dashboard\n // $location.path(\"/\");\n }\n /**\r\n * Delete Report\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteReportClicked() {\n var status = _report.status;\n var title = \"Warning\";\n\n if (status == 'synched') {\n title = \"Attention\";\n }\n\n bootbox.dialog({\n message: \"Please confirm that you wish to reset this Cabin Report.\",\n title: \"\" + title + \"\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n danger: {\n label: \"Reset Cabin Report\",\n className: \"btn-warning\",\n callback: function callback() {\n //store report details\n var guid = _report.ReportGuid;\n var status = _report.Status; // remove report from temp location and\n // possibly from permanent location\n\n CabinReportLocalEditFactory.deleteReport(_report.ReportGuid);\n CrewAssessmentFactory.updateCrewMembers(_report.CCMSCrewPositions, _report.Route, _report.DutyDate); // delete the temp report\n\n CabinReportLocalEditFactory.deleteTempReport();\n FlightFactory.updateFlightFromReport(_report); //reuse guid if this was report was never sent to the server\n\n if (status == 'draft' || status == 'completed') ReportGuidFactory.restoreGuid(_report.ReportGuid); // set editing page to none\n\n SettingsMain.setEditingPage(null); // next code moves user to main page\n\n $timeout(function () {\n if ($location.path() == \"/report/temp\") {\n $scope.openReport();\n } else {\n $route.reload();\n }\n });\n }\n }\n }\n });\n }\n /**\r\n * increase row no of travel value\r\n * @memberof ReportCtrl\r\n */\n\n\n function plusTravelValueIncompleteRow() {\n if (!_report.TravelValueIncompleteRow && _report.TravelValueIncompleteRow != 0) _report.TravelValueIncompleteRow = 0;else _report.TravelValueIncompleteRow++;\n if (_report.TravelValueIncompleteRow > 99) _report.TravelValueIncompleteRow = 99;\n $scope.reportItemValueChanged();\n }\n /**\r\n * decrease row no of travel value\r\n * @memberof ReportCtrl\r\n */\n\n\n function minusTravelValueIncompleteRow() {\n if (!_report.TravelValueIncompleteRow && _report.TravelValueIncompleteRow != 0) _report.TravelValueIncompleteRow = 0;else _report.TravelValueIncompleteRow--;\n if (_report.TravelValueIncompleteRow < 0) _report.TravelValueIncompleteRow = 0;\n $scope.reportItemValueChanged();\n }\n /**\r\n * travel value changed\r\n * @memberof ReportCtrl\r\n */\n\n\n function reportTravelIncompleteChanged() {\n if (!_report.TravelIncomplete) {\n _report.TravelValueIncompleteRow = null;\n _report.TravelValueIncompleteReason = null;\n }\n\n $scope.reportItemValueChanged();\n }\n /**\r\n * When report changes run to update the item\r\n * @memberof ReportCtrl\r\n */\n\n\n function reportChanged(item) {\n // put preset comments\n if (item != null) {\n if (item.PresetComments != null) {\n if (item.ItemValue == null || item.ItemValue == '') {\n item.ItemValue = item.PresetComments;\n }\n }\n } // update the report totals\n\n\n _report.updateTotals(); // save the report to a temp place\n\n\n if (_report.Status != 'synched') _report.saveReportAsTemp();\n } //CCMS\n\n /**\r\n * make the ccms positions\r\n * @memberof ReportCtrl\r\n */\n\n\n function reportCCMSPositions() {\n var reportCCMSPositions = new Array();\n var allCCMSPositions = CCMSFactory.getCCMSFromStorage();\n\n for (var i = 0; i < allCCMSPositions.length; i++) {\n // find the positions for this aircraft type\n if (allCCMSPositions[i].Aircraft == _report.AcType) {\n for (var j = 0; j < allCCMSPositions[i].Positions.length; j++) {\n reportCCMSPositions.push(allCCMSPositions[i].Positions[j].Position);\n }\n }\n }\n\n return reportCCMSPositions;\n }\n /**\r\n * Open confirmation modal for coping ccms \r\n * @memberof ReportCtrl\r\n */\n\n\n function copyCcmsPositions() {\n bootbox.dialog({\n message: \"Copy CCMS positions from previous leg?
Attention: Any current CCMS data will be overwritten\",\n title: \"CCMS Copy\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n copyCcmsPositionsFinal();\n $timeout($scope.reportItemValueChanged);\n }\n }\n }\n });\n }\n /**\r\n * copy positions from previous leg, to minimize input, normally, ac performs several legs in a row with the same crew, each at the same position on all legs \r\n * @memberof ReportCtrl\r\n */\n\n\n function copyCcmsPositionsFinal() {\n if (_report.CCMSCrewPositions == null || _report.CCMSCrewPositions.length == 0) return;\n var guid = _report.ReportGuid;\n var ac = _report.AcTailNo;\n var dt = _report.ScheduledDepartureDateUTC;\n var tm = _report.ScheduledDepartureTimeUTC;\n var previousCcms = CabinReportLocalEditFactory.getPreviousCabinReportCcmsPositions(guid, ac, dt, tm);\n\n if (previousCcms != null && previousCcms.length > 0) {\n var posX, posI, found; //TODO: Special treatment for manual entries: Add new ones, update existing will data (Id, Initials, Name, Position, CCMS)\n //loop all previous report positions\n\n for (var i = 0; i < previousCcms.length; i++) {\n posI = previousCcms[i];\n found = false; //loop all report positions\n\n for (var x = 0; x < _report.CCMSCrewPositions.length; x++) {\n posX = _report.CCMSCrewPositions[x]; //check for match\n\n if (posX.CrewId != null && posX.CrewId != '' && posI.CrewId != null && posI.CrewId != '' && posX.CrewId == posI.CrewId || posX.Initials != null && posX.Initials != '' && posI.Initials != null && posI.Initials != '' && posX.Initials == posI.Initials) {\n //copy only if source has CCMS set\n if (posI.CCMS != null && posI.CCMS != '') {\n //old crew matched to current crew\n posX.CCMS = posI.CCMS;\n found = true;\n break;\n }\n }\n } //if old record was a manual entry and not found in the current crew list, add it also here as manual\n\n\n if (posI.IsManual == true && !found) {\n //console.debug(posI);\n //console.debug(report);\n _report.CCMSCrewPositions.push(posI); //console.debug('Add code to copy manual crew member in this current report crew');\n\n }\n }\n }\n\n var s = '';\n } //UMNumber\n\n /**\r\n * increases UM number \r\n * @memberof ReportCtrl\r\n */\n\n\n function plusUMNumber() {\n _report.UMNumber++;\n if (_report.UMNumber > 200) _report.UMNumber = 200;\n $scope.reportItemValueChanged();\n }\n /**\r\n * decreases UM number \r\n * @memberof ReportCtrl\r\n */\n\n\n function minusUMNumber() {\n _report.UMNumber--;\n if (_report.UMNumber < 0) _report.UMNumber = 0;\n $scope.reportItemValueChanged();\n }\n /**\r\n * Clear UM number \r\n * @memberof ReportCtrl\r\n */\n\n\n function clearUMNumber() {\n _report.UMNumber = 0;\n $scope.reportItemValueChanged();\n } //Luggage Number\n\n /**\r\n * increases Luggage number \r\n * @memberof ReportCtrl\r\n */\n\n\n function plusLuggageNumber() {\n _report.LuggageNumber++;\n if (_report.LuggageNumber > 100) _report.LuggageNumber = 100;\n $scope.reportItemValueChanged();\n }\n /**\r\n * decreases Luggage number \r\n * @memberof ReportCtrl\r\n */\n\n\n function minusLuggageNumber() {\n _report.LuggageNumber--;\n if (_report.LuggageNumber < 0) _report.LuggageNumber = 0;\n $scope.reportItemValueChanged();\n }\n /**\r\n * Clear Luggage number \r\n * @memberof ReportCtrl\r\n */\n\n\n function clearLuggageNumber() {\n _report.LuggageNumber = 0;\n $scope.reportItemValueChanged();\n } // Bars Trolleys\n\n /**\r\n * define open bar/trolley dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openBarTrolleyModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgBar.html',\n controller: 'BarTrolleyCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n bart: function bart() {\n return inputObject;\n }\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.BarTrolleys.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n $scope.reportItemValueChanged();\n });\n }\n /**\r\n * add new bar/trolley\r\n * @memberof ReportCtrl\r\n */\n\n\n function addNewBarTrolley() {\n try {\n openBarTrolleyModal(null);\n } catch (e) {\n LogService.debug(\"template barTrolley url (null)\", e);\n }\n }\n /**\r\n * edit bar/trolley\r\n * @memberof ReportCtrl\r\n */\n\n\n function editBarTrolley(bart) {\n try {\n openBarTrolleyModal(bart);\n } catch (e) {\n LogService.debug(\"template barTrolley url (bart)\", e);\n }\n }\n /**\r\n * delete bar/trolley\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteBarTrolley(bart) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this record?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n BarTrolleyFactory.deleteFromList(bart, _report.BarTrolleys);\n $timeout($scope.reportItemValueChanged);\n }\n }\n }\n });\n } // function showOrHideBarTrolleyInputs() {\n // \tdebugger;\n // \t$scope.showBarTrolleyUploadImage = $scope.report.BarTrolleys.filter(function (arg) { return filterPhotos(arg); }).length > 0 || $scope.report.BarTrolleys.length == 0;\n // \t$scope.showBarTrolleyInsertData = !$scope.report.BarTrolleys.filter(function (arg) { return filterPhotos(arg); }).length > 0 || $scope.report.BarTrolleys.length == 0;\n // }\n // function filterPhotos(arg) {\n // \tif (arg == null) {\n // \t\treturn [];\n // \t}\n // \telse {\n // \t\treturn arg.photos;\n // \t}\n // }\n // CCMS \n\n /**\r\n * define open ccms crew position dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openCCMSCrewPositionModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgCrew.html',\n controller: 'CCMSCrewPositionCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n crew: function crew() {\n return inputObject;\n }\n }\n }).result.then(function (result) {\n if (result != null && result.Object != null) {\n //check if the same crew member already exists\n var unique = true;\n var errorField = null;\n\n if (result.Object.CrewId != null && result.Object.CrewId != '') {\n if (_report.CCMSCrewPositions.filter(function (x) {\n return x.CrewId == result.Object.CrewId;\n }, true).length > 0) {\n unique = false;\n errorField = \"id\";\n }\n }\n\n if (result.Object.Initials != null && result.Object.Initials != '') {\n if (_report.CCMSCrewPositions.filter(function (x) {\n return x.Initials.toUpperCase() == result.Object.Initials.toUpperCase();\n }, true).length > 0) {\n unique = false;\n errorField = \"initials\";\n }\n }\n\n if (unique) {\n if (result.isInsertMode) {\n _report.CCMSCrewPositions.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n\n $scope.reportItemValueChanged();\n } else {\n bootbox.alert(\"

Warning

Crew member with given \" + errorField + \", already exists in this flight's crew and you may not add it again!\");\n }\n }\n });\n }\n /**\r\n * add new ccms crew positio\r\n * @memberof ReportCtrl\r\n */\n\n\n function addNewCCMSCrewPosition() {\n openCCMSCrewPositionModal(null);\n } //TODO REMOVE UNUSED\n\n /**\r\n * edit ccms crew position\r\n * @memberof ReportCtrl\r\n */\n\n\n function editCCMSCrewPosition(crew) {\n openCCMSCrewPositionModal(crew);\n }\n /**\r\n * delete ccms crew position\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteCCMSCrewPosition(crew) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this record?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n CCMSCrewPositionFactory.deleteFromList(crew, _report.CCMSCrewPositions);\n $timeout($scope.reportItemValueChanged);\n }\n }\n }\n });\n } // Grooming issue modal\n\n\n $scope.openGroomingForm = function (crew) {\n if (!$scope.groomingReportsByCrew) {\n $scope.groomingReportsByCrew = GroomingCategoriesFactory.loadGroomingReports();\n } // Fetch existing data or initialize default data\n\n\n var existingData = $scope.groomingReportsByCrew[crew.CrewId];\n var groomingData = existingData || groomingCategories.map(function (category) {\n return {\n Id: category.Id,\n Label: category.Label,\n Description: category.Description,\n OrderNo: category.OrderNo,\n UserInput: ''\n };\n });\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgGroomingIssue.html',\n controller: 'GroomimgCategoriesModalCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n crewData: function crewData() {\n return crew;\n },\n groomingCategories: function groomingCategories() {\n return groomingData;\n }\n }\n }).result.then(function (result) {\n if (result) {\n // Save all categories for this crew, preserving the display of unfilled ones\n $scope.groomingReportsByCrew[crew.CrewId] = result; // Filter and log only completed categories\n\n var completedCategories = result.filter(function (category) {\n return category.UserInput && category.UserInput.trim() !== '';\n });\n }\n });\n }; // Flight Detail\n\n\n function openFlightDetailModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgFlightDetail.html',\n controller: 'FlightDetailCtrl',\n size: 'md',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n fd: function fd() {\n return inputObject;\n }\n }\n }).result.then(function (result) {\n if (result != null) {\n angular.extend(inputObject, result.Object);\n }\n\n $scope.reportItemValueChanged();\n });\n } // First Aid Kit\n\n /**\r\n * define open first aid kit dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openFirstAidKitModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgFirstAid.html',\n controller: 'FirstAidKitCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n fak: function fak() {\n return inputObject;\n },\n IsEMK: inputObject != null && inputObject.IsEMK\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.FirstAidKits.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n $scope.reportItemValueChanged();\n });\n }\n /**\r\n * add new EMK first aid kit\r\n * @memberof ReportCtrl\r\n */\n\n\n function addNewEMKFirstAidKit() {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgFirstAid.html',\n controller: 'FirstAidKitCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n fak: null,\n IsEMK: true\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.FirstAidKits.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n $scope.reportItemValueChanged();\n });\n }\n /**\r\n * add new first aid kit\r\n * @memberof ReportCtrl\r\n */\n\n\n function addNewFirstAidKit() {\n openFirstAidKitModal(null);\n }\n /**\r\n * edit first aid kit\r\n * @memberof ReportCtrl\r\n */\n\n\n function editFirstAidKit(fak) {\n openFirstAidKitModal(fak);\n }\n /**\r\n * delete first aid kit\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteFirstAidKit(fak) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this record?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n FirstAidKitFactory.deleteFromList(fak, _report.FirstAidKits);\n $timeout($scope.reportItemValueChanged);\n }\n }\n }\n });\n } // Medical Incidents\n\n /**\r\n * define open medical incident dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openMedicalIncidentModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgMedical.html',\n controller: 'MedicalIncidentCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n med: function med() {\n return inputObject;\n }\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.MedicalIncidents.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n $scope.reportItemValueChanged();\n }); //HACK FOR IOS:: Trying to sign, scrolls the modal dialog\n //following code, fixes that issue, but it is not a good looking solution\n\n $timeout(function () {\n if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\n $('.modal').css({\n position: 'absolute',\n marginTop: $(window).scrollTop() + 'px',\n bottom: 'auto'\n });\n $('.modal-backdrop').css({\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: Math.max(document.body.scrollHeight, document.documentElement.scrollHeight, document.body.offsetHeight, document.documentElement.offsetHeight, document.body.clientHeight, document.documentElement.clientHeight) + 'px'\n });\n }\n }, 1000, false);\n }\n /**\r\n * add new medical incident\r\n * @memberof ReportCtrl\r\n */\n\n\n function addNewMedicalIncident() {\n openMedicalIncidentModal(null);\n }\n /**\r\n * edit medical incident\r\n * @memberof ReportCtrl\r\n */\n\n\n function editMedicalIncident(med) {\n openMedicalIncidentModal(med);\n }\n /**\r\n * delete medical incident\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteMedicalIncident(med) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this record?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n MedicalIncidentFactory.deleteFromList(med, _report.MedicalIncidents);\n $scope.reportItemValueChanged();\n $scope.$apply();\n }\n }\n }\n });\n } // Special meals\n\n /**\r\n * define open special meal issue dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openSpecialMealIssueModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgSpecialMeal.html',\n controller: 'SpecialMealIssueCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n smi: function smi() {\n return inputObject;\n }\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.SpecialMealIssues.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n $scope.reportItemValueChanged();\n });\n }\n /**\r\n * add new special meal issue\r\n * @memberof ReportCtrl\r\n */\n\n\n function addNewSpecialMealIssue() {\n openSpecialMealIssueModal(null);\n }\n /**\r\n * edit special meal issue\r\n * @memberof ReportCtrl\r\n */\n\n\n function editSpecialMealIssue(smi) {\n openSpecialMealIssueModal(smi);\n }\n /**\r\n * delete special meal issue\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteSpecialMealIssue(smi) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this record?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n SpecialMealIssueFactory.deleteFromList(smi, _report.SpecialMealIssues);\n $timeout($scope.reportItemValueChanged);\n }\n }\n }\n });\n } // Supplies\n\n /**\r\n * define open supply dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openSupplyModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgSupply.html',\n controller: 'SupplyCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n sup: function sup() {\n return inputObject;\n }\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.Supplies.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n $scope.reportItemValueChanged();\n });\n }\n /**\r\n * add new supply\r\n * @memberof ReportCtrl\r\n */\n\n\n function addNewSupply() {\n openSupplyModal(null);\n }\n /**\r\n * edit supply\r\n * @memberof ReportCtrl\r\n */\n\n\n function editSupply(sup) {\n openSupplyModal(sup);\n }\n /**\r\n * delete supply\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteSupply(sup) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this record?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n SupplyFactory.deleteFromList(sup, _report.Supplies);\n $timeout($scope.reportItemValueChanged);\n }\n }\n }\n });\n } // Seat Upgrades\n\n\n checkEligibleUpgrades();\n /**\r\n * define open upgrade dialog function\r\n * @memberof ReportCtrl\r\n */\n\n function checkEligibleUpgrades() {\n var eligiblePassengers = [];\n var paxInfo = null;\n PaxInfoFactory.getPaxInfoFromStorage(_report.FlightId, function (result) {\n paxInfo = result;\n\n if (paxInfo && paxInfo.Seatmap) {\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n if (paxInfo.Seatmap[i].Columns[j].IsEligibleForUpgrade && paxInfo.Seatmap[i].Columns[j].Cabin == 'Y') {\n var alreadyUpgraded = false;\n\n for (var k = 0; k < _report.UpgradedPassengers.length; k++) {\n if (_report.UpgradedPassengers[k].UCI == paxInfo.Seatmap[i].Columns[j].UCI && _report.UpgradedPassengers[k].PNR == paxInfo.Seatmap[i].Columns[j].PNR && _report.UpgradedPassengers[k].OriginalSeatNo == paxInfo.Seatmap[i].Columns[j].SeatNo) {\n alreadyUpgraded = true;\n }\n }\n\n if (!alreadyUpgraded) {\n eligiblePassengers.push(paxInfo.Seatmap[i].Columns[j]);\n }\n }\n }\n }\n }\n\n $scope.eligiblePassengers = eligiblePassengers.length;\n });\n }\n /**\r\n * define open upgrade dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openUPGDModal(inputObject) {\n PaxInfoFactory.getPaxInfoFromStorage(_report.FlightId, function (_paxInfo) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgUPGD.html',\n controller: 'UPGDCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n upgradedPassenger: function upgradedPassenger() {\n return inputObject;\n },\n report: function report() {\n return _report;\n },\n paxInfo: function paxInfo() {\n return _paxInfo;\n }\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.UpgradedPassengers.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n checkEligibleUpgrades();\n $scope.reportItemValueChanged();\n });\n });\n }\n /**\r\n * add new Upgrade\r\n * @memberof ReportCtrl\r\n */\n\n\n function addNewUPGD() {\n openUPGDModal(null);\n }\n /**\r\n * edit Upgrade\r\n * @memberof ReportCtrl\r\n */\n\n\n function editUPGD(upgradedPassenger) {\n openUPGDModal(upgradedPassenger);\n }\n /**\r\n * delete Upgrade\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteUPGD(upgradedPassenger) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this record?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n _report.UpgradedPassengers = _report.UpgradedPassengers.filter(function (p) {\n return p.OriginalSeatNo != upgradedPassenger.OriginalSeatNo && p.UCI != upgradedPassenger.UCI;\n });\n checkEligibleUpgrades();\n $timeout($scope.reportItemValueChanged);\n }\n }\n }\n });\n } // Change Seat\n\n\n $scope.allPassengers = 0;\n getAllPasseengersCounter();\n\n function getAllPasseengersCounter() {\n PaxInfoFactory.getPaxInfoFromStorage(_report.FlightId, function (result) {\n var paxInfo = result;\n var allPassengers = [];\n\n if (paxInfo) {\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n if (paxInfo.Seatmap[i].Columns[j].SeatNo && !paxInfo.Seatmap[i].Columns[j].IsEmptySeat) {\n allPassengers.push(paxInfo.Seatmap[i].Columns[j]);\n }\n }\n }\n }\n\n $scope.allPassengers = allPassengers.length;\n });\n }\n /**\r\n * define open change seat dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openChangeSeatModal(inputObject) {\n PaxInfoFactory.getPaxInfoFromStorage(_report.FlightId, function (_paxInfo2) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgSeatChange.html',\n controller: 'SeatChangeCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n changedSeat: function changedSeat() {\n return inputObject;\n },\n report: function report() {\n return _report;\n },\n paxInfo: function paxInfo() {\n return _paxInfo2;\n }\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.ChangedSeats.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n $scope.reportItemValueChanged();\n });\n });\n }\n /**\r\n * add new seat change\r\n * @memberof ReportCtrl\r\n */\n\n\n function addNewChangedSeat() {\n openChangeSeatModal(null);\n }\n /**\r\n * edit changed seat\r\n * @memberof ReportCtrl\r\n */\n\n\n function editChangedSeat(changedSeat) {\n openChangeSeatModal(changedSeat);\n }\n /**\r\n * delete changed seat\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteChangedSeat(changedSeat) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this record?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n _report.ChangedSeats = _report.ChangedSeats.filter(function (p) {\n return p.OriginalSeatNo != changedSeat.OriginalSeatNo && p.UCI != changedSeat.UCI;\n });\n $timeout($scope.reportItemValueChanged);\n }\n }\n }\n });\n } // Travel value seal \n\n /**\r\n * define open travel value seal dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openTravelValueSealModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgTravelValueSeal.html',\n controller: 'TravelValueSealCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n tvs: function tvs() {\n return inputObject;\n }\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.TravelValueSeals.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n $scope.reportItemValueChanged();\n });\n }\n /**\r\n * add new travel value seal\r\n * @memberof ReportCtrl\r\n */\n\n\n function addNewTravelValueSeal() {\n openTravelValueSealModal(null);\n }\n /**\r\n * edit travel value seal\r\n * @memberof ReportCtrl\r\n */\n\n\n function editTravelValueSeal(tvs) {\n openTravelValueSealModal(tvs);\n }\n /**\r\n * delete travel value seal\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteTravelValueSeal(tvs) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this record?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n TravelValueSealFactory.deleteFromList(tvs, _report.TravelValueSeals);\n $timeout($scope.reportItemValueChanged);\n }\n }\n }\n });\n } // Incomplete In-flight Services \n\n /**\r\n * define open Incomplete In-flight Service dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openIncompleteServiceModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgIncompleteServices.html',\n controller: 'IncompleteServicesIssueCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n service: function service() {\n return inputObject;\n },\n fleetId: function fleetId() {\n return flight.Fleet.Id;\n }\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.IncompleteServices.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n $scope.reportItemValueChanged();\n });\n }\n /**\r\n * add new travel value seal\r\n * @memberof ReportCtrl\r\n */\n\n\n function addIncompleteService() {\n openIncompleteServiceModal(null);\n }\n /**\r\n * edit travel value seal\r\n * @memberof ReportCtrl\r\n */\n\n\n function editIncompleteService(service) {\n openIncompleteServiceModal(service);\n }\n /**\r\n * delete travel value seal\r\n * @memberof ReportCtrl\r\n */\n\n\n function deleteIncompleteService(service) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this record?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n IncompleteServicesIssueFactory.deleteFromList(service, _report.IncompleteServices);\n $timeout($scope.reportItemValueChanged);\n }\n }\n }\n });\n }\n /**\r\n \t\t* add new additional feedback\r\n \t\t* @memberof ReportCtrl\r\n \t\t*/\n\n\n function addAdditionalFeedback() {\n openAdditionalFeedbackModal(null);\n }\n /**\r\n * edit additional feedback\r\n * @memberof ReportCtrl\r\n */\n\n\n function editAdditionalFeedback(feedback) {\n openAdditionalFeedbackModal(feedback);\n } // First Aid Kit\n\n /**\r\n * define open first aid kit dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openAdditionalFeedbackModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgAdditionalFeedback.html',\n controller: 'AdditionalFeedbackCtrl',\n size: 'lg',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n feedback: function feedback() {\n return inputObject;\n }\n }\n }).result.then(function (result) {\n if (result != null) {\n if (result.isInsertMode) {\n _report.FirstAidKits.push(result.Object);\n } else {\n angular.extend(inputObject, result.Object);\n }\n }\n\n $scope.reportItemValueChanged();\n });\n } //TimePicker times - convert to Date UTC\n\n\n $scope.BoardingDisembarkationTimes = {\n FirstPaxDisembarkationTime: $scope.report.FirstPaxDisembarkationTime ? new Date($scope.report.FirstPaxDisembarkationTime).toUTC() : null,\n LastPaxDisembarkationTime: $scope.report.LastPaxDisembarkationTime ? new Date($scope.report.LastPaxDisembarkationTime).toUTC() : null,\n FirstPaxTime: $scope.report.FirstPaxTime ? new Date($scope.report.FirstPaxTime).toUTC() : null,\n LastPaxTime: $scope.report.LastPaxTime ? new Date($scope.report.LastPaxTime).toUTC() : null\n }; // Boarding times\n\n var hasFirstTime = false;\n var hasLastTime = false;\n $scope.FirstPaxGetTimeUTC = firstPaxGetTimeUTC;\n $scope.LastPaxGetTimeUTC = lastPaxGetTimeUTC;\n $scope.firstPaxTimeChanged = firstPaxTimeChanged;\n $scope.lastPaxTimeChanged = lastPaxTimeChanged;\n\n function firstPaxTimeChanged() {\n if (!hasFirstTime) {\n firstPaxGetTimeUTC();\n hasFirstTime = true;\n } else {\n //From timepicker(date) to report(moment)\n var dateObj = new Date($scope.BoardingDisembarkationTimes.FirstPaxTime).fromUTC();\n $scope.report.FirstPaxTime = moment(dateObj);\n }\n }\n\n function lastPaxTimeChanged() {\n if (!hasLastTime) {\n lastPaxGetTimeUTC();\n hasLastTime = true;\n } else {\n //From timepicker(date) to report(moment)\n var dateObj = new Date($scope.BoardingDisembarkationTimes.LastPaxTime).fromUTC();\n $scope.report.LastPaxTime = moment(dateObj);\n }\n }\n\n function firstPaxGetTimeUTC() {\n $scope.report.FirstPaxTime = moment.utc(); //convert to date for uib timepicker\n\n $scope.BoardingDisembarkationTimes.FirstPaxTime = moment($scope.report.FirstPaxTime).toDate().toUTC();\n saveDraftClicked();\n }\n\n function lastPaxGetTimeUTC() {\n $scope.report.LastPaxTime = moment.utc(); //convert to date for uib timepicker\n\n $scope.BoardingDisembarkationTimes.LastPaxTime = moment($scope.report.LastPaxTime).toDate().toUTC();\n saveDraftClicked();\n } // Disembarkation times\n\n\n var hasFirstDisembarkationTime = false;\n var hasLastDisembarkationTime = false;\n $scope.FirstPaxGetDisembarkationTimeUTC = firstPaxGetDisembarkationTimeUTC;\n $scope.LastPaxGetDisembarkationTimeUTC = lastPaxGetDisembarkationTimeUTC;\n $scope.firstPaxDisembarkationTimeChanged = firstPaxDisembarkationTimeChanged;\n $scope.lastPaxDisembarkationTimeChanged = lastPaxDisembarkationTimeChanged;\n\n function firstPaxDisembarkationTimeChanged() {\n if (!hasFirstDisembarkationTime) {\n firstPaxGetDisembarkationTimeUTC();\n hasFirstDisembarkationTime = true;\n } else {\n //From timepicker(date) to report(moment)\n var dateObj = new Date($scope.BoardingDisembarkationTimes.FirstPaxDisembarkationTime).fromUTC();\n $scope.report.FirstPaxDisembarkationTime = moment(dateObj);\n }\n }\n\n function lastPaxDisembarkationTimeChanged() {\n if (!hasLastDisembarkationTime) {\n lastPaxGetDisembarkationTimeUTC();\n hasLastDisembarkationTime = true;\n } else {\n //From timepicker(date) to report(moment)\n var dateObj = new Date($scope.BoardingDisembarkationTimes.LastPaxDisembarkationTime).fromUTC();\n $scope.report.LastPaxDisembarkationTime = moment(dateObj);\n }\n }\n\n function firstPaxGetDisembarkationTimeUTC() {\n //apply moment time in report\n $scope.report.FirstPaxDisembarkationTime = moment.utc(); //convert to date for uib timepicker\n\n $scope.BoardingDisembarkationTimes.FirstPaxDisembarkationTime = moment($scope.report.FirstPaxDisembarkationTime).toDate().toUTC();\n saveDraftClicked();\n }\n\n function lastPaxGetDisembarkationTimeUTC() {\n $scope.report.LastPaxDisembarkationTime = moment.utc(); //convert to date for uib timepicker\n\n $scope.BoardingDisembarkationTimes.LastPaxDisembarkationTime = moment($scope.report.LastPaxDisembarkationTime).toDate().toUTC();\n saveDraftClicked();\n } //Item Photos\n\n /**\r\n * define open item photos dialog function\r\n * @memberof ReportCtrl\r\n */\n\n\n function openItemPhotosModal(inputObject) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgItemPhotos.html',\n controller: 'ItemPhotosCtrl',\n size: 'md',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n item: function item() {\n return inputObject;\n }\n }\n }).result.then(function (result) {\n $scope.reportItemValueChanged();\n });\n }\n /**\r\n * attach Photo On Various Item\r\n * @memberof ReportCtrl\r\n */\n\n\n function attachPhotoOnVariousItem(item) {\n openItemPhotosModal(item);\n }\n /**\r\n * attach Photo On Various Item\r\n * @memberof ReportCtrl\r\n */\n\n\n function attachPhotoOnBarTrolley(item) {\n if (item == undefined) {\n var x = BarTrolleyFactory.createNew();\n item = x;\n\n _report.BarTrolleys.push(item);\n }\n\n openItemPhotosModal(item);\n }\n\n $scope.autoAdjustTarget = null;\n $scope.autoAdjustTimer = null;\n\n $scope.autoAdjustElement = function (element) {\n if (element) {\n autoAdjustTextarea(element);\n }\n };\n\n $scope.autoAdjustRun = function () {\n var t = $scope.autoAdjustTarget;\n $scope.autoAdjustElement(t);\n $scope.autoAdjustTarget = null;\n $scope.autoAdjustTimer = null; // also, update the report and save it to a temp place\n\n _report.updateTotals();\n\n if (_report.Status != 'synched') _report.saveReportAsTemp();\n };\n\n $scope.adjustTextarea = function ($event) {\n // $event.keyCode = 13\n // performing adjusts using a timer, to minimize times it executes, and\n // make it faster on ipad2\n if ($scope.autoAdjustTimer != null) {\n clearTimeout($scope.autoAdjustTimer); // old object pending... execute its adjustment and then plan new\n // object's adjustment\n\n if ($event.target != $scope.autoAdjustTarget) {\n $scope.autoAdjustRun();\n }\n }\n\n $scope.autoAdjustTarget = $event.target;\n $scope.autoAdjustTimer = setTimeout($scope.autoAdjustRun, 500);\n };\n /**\r\n * It handles the cabin report when u want to navigate to another view\r\n * @memberof CabinReports\r\n * @param {Object} report input the cabin report \r\n */\n\n\n function handleIfReport(report) {\n if ($scope.state == 'report') {\n if (report == null) {\n report = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(report.FlightId);\n } // delete the temp report\n\n\n CabinReportLocalEditFactory.deleteTempReport(); //reuse guid if this was a new report\n\n if (report.Status == 'pending') ReportGuidFactory.restoreGuid(report.ReportGuid);\n }\n }\n\n $scope.BarSealsImage = [];\n $scope.BarSealsImageRemarks;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('ReportGuidFactory', ReportGuidFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ReportGuidFactory\r\n * @description \r\n * Manages ReportGuid\r\n * @ngInject\r\n */\n\n function ReportGuidFactory(localStorageMD5Service, GenericService) {\n /**\r\n * Initialize the ReportGuid\r\n * @memberof ReportGuidFactory\r\n */\n function ReportGuid() {\n this.Guid = null;\n }\n\n var objType = 'reportGuids';\n var objCallback = ReportGuid;\n var service = {\n getNextGuid: getNextGuid,\n setReportGuidsToStorage: setReportGuidsToStorage,\n restoreGuid: restoreGuid,\n getRemainingReportGuids: getRemainingReportGuids\n };\n /**\r\n * Extend Object from the default ReportGuid Object\r\n * @memberof ReportGuidFactory\r\n * @param {Object} obj a ReportGuid\r\n * @returns {Object} ReportGuid\r\n */\n\n function fromObject(obj) {\n if (obj == null) return null;\n var reportGuid = new ReportGuid();\n reportGuid.Guid = obj;\n return reportGuid;\n }\n\n ;\n /**\r\n * Extend an array of Objects from the default ReportGuid Object\r\n * @memberof ReportGuidFactory\r\n * @param {Array} objList an Array Of ReportGuids\r\n * @returns {Array} ReportGuids\r\n */\n\n function fromObjectList(objList) {\n if (objList == null) return null;\n var arrayLength = objList.length;\n var reportGuids = new Array();\n\n for (var i = 0; i < arrayLength; i++) {\n var reportGuid = new ReportGuid();\n reportGuid.Guid = objList[i];\n reportGuids.push(reportGuid);\n }\n\n return reportGuids;\n }\n\n ;\n /**\r\n * Get all the ReportGuid's guid from given list\r\n * @memberof ReportGuidFactory\r\n * @param {array} objectList An object list\r\n * @returns {array} guids\r\n */\n\n function toObjectList(guidList) {\n if (guidList == null) return null;\n var arrayLength = guidList.length;\n var objList = new Array();\n\n for (var i = 0; i < arrayLength; i++) {\n objList.push(guidList[i].Guid);\n }\n\n return objList;\n }\n\n ;\n /**\r\n * Get all the reportGuid objects\r\n * @memberof reportGuid\r\n * @returns {array} ACSupplies\r\n */\n\n function getReportGuidsFromStorage() {\n var reportGuids = localStorageMD5Service.get('reportGuids');\n return fromObjectList(reportGuids);\n }\n /**\r\n * Set all the reportGuid objects\r\n * @memberof ReportGuidFactory\r\n * @return {string} reportGuid\r\n */\n\n\n function setReportGuidsToStorage(reportGuids) {\n GenericService.saveAll(reportGuids, objType, objCallback);\n }\n /**\r\n * Delete all the reportGuid objects\r\n * @memberof ReportGuidFactory\r\n */\n\n\n function clearReportGuidsFromStorage() {\n GenericService.removeAll(objType, objCallback);\n }\n /**\r\n * Get the next available guid and remove it from pool\r\n * @memberof ReportGuidFactory\r\n * @return {string} reportGuid\r\n */\n\n\n function getNextGuid() {\n var reportGuids = getReportGuidsFromStorage();\n if (reportGuids == null) return null;\n var validGuidIndex = -1;\n var resultingGuid = null;\n\n for (var i = 0; i < reportGuids.length; i++) {\n if (reportGuids[i].Guid != null && reportGuids[i].Guid != '') {\n validGuidIndex = i;\n resultingGuid = reportGuids[i].Guid;\n break;\n }\n }\n\n if (validGuidIndex >= 0) {\n // remove the guid from the array\n reportGuids.splice(validGuidIndex, 1); // save the new array\n\n setReportGuidsToStorage(toObjectList(reportGuids));\n }\n\n return resultingGuid;\n }\n /**\r\n * Restore previously used guid into the pool of guids,Used when a report is being cancelled or deleted (and it has not been sent to the server)\r\n * @memberof ReportGuidFactory\r\n * @param {string} reportGuid\r\n */\n\n\n function restoreGuid(guid) {\n //reject incorrect values\n if (typeof guid == 'undefined' || guid == null || guid == '') return false;\n var reportGuids = getReportGuidsFromStorage();\n if (reportGuids == null) reportGuids = [];\n var arrayLength = reportGuids.length;\n\n for (var i = 0; i < arrayLength; i++) {\n if (reportGuids[i].Guid == guid) {\n return false;\n }\n } //add the guid into the pool of guids\n\n\n var repGuid = fromObject(guid);\n reportGuids.push(repGuid); // save the new array\n\n setReportGuidsToStorage(toObjectList(reportGuids));\n return true;\n }\n /**\r\n * Get the count of remaining reportGuid objects\r\n * @memberof reportGuid\r\n * @returns {number} reportGuidsLength\r\n */\n\n\n function getRemainingReportGuids() {\n var reportGuids = getReportGuidsFromStorage();\n if (reportGuids == null) return 0;\n return reportGuids.length;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('ReportsHistoryCtrl', ReportsHistoryCtrl);\n\n function ReportsHistoryCtrl($scope, $routeParams, $timeout, ReportsHistoryFactory, FlightFactory) {\n var reportId = $routeParams.reportId;\n var flightId = $routeParams.flightId;\n var reportType = $routeParams.reportType;\n var flight = FlightFactory.getFlightFromStorage(flightId);\n window.addEventListener('online', function (e) {\n $timeout(checkConnectionStatus());\n });\n $scope.reports = [];\n $scope.flight = flight;\n $scope.contentToShow = \"loading\";\n $scope.errorMessage = \"\";\n $scope.showImage = showImage;\n $scope.imageData = \"\";\n $scope.closeImage = closeImage;\n\n $scope.init = function () {\n checkConnectionStatus();\n };\n\n $scope.init();\n /**\r\n * Fetches the reports\r\n * @memberof ReportsHistoryCtrl \r\n */\n\n function fetchReports() {\n ReportsHistoryFactory.getReportsHistory(reportId, reportType).then(function (response) {\n return handleResponse(response);\n })[\"catch\"](function () {\n showError(\"We could not get any reports!\");\n });\n }\n /**\r\n * Displays the error message\r\n * @memberof ReportsHistoryCtrl \r\n * @param {string} message message to display\r\n */\n\n\n function showError(message) {\n $scope.contentToShow = \"error\";\n $scope.errorMessage = message;\n }\n /**\r\n * Checks if the client is online or offline \r\n * if is online fetches the reports else displays relative message\r\n * @memberof ReportsHistoryCtrl \r\n */\n\n\n function checkConnectionStatus() {\n var isOnline = window.navigator.onLine;\n\n if (isOnline) {\n fetchReports();\n } else {\n showError(\"Please check the internet connection!\");\n }\n }\n /**\r\n * Handles the response from the API \r\n * if is success displays the reports else shows the error message.\r\n * @memberof ReportsHistoryCtrl \r\n * @param {object} response the response object from API\r\n */\n\n\n function handleResponse(response) {\n if (response.data.success) {\n if (response.data.data.length > 0) {\n $scope.contentToShow = \"reports\";\n $scope.reports = response.data.data;\n } else {\n showError(\"There are no reports for this flight!\");\n }\n } else {\n showError(\"We could not get any reports!\");\n }\n }\n /**\r\n * Displays the image in full screen\r\n * @memberof ReportsHistoryCtrl \r\n * @param {object} ImageData The\r\n */\n\n\n function showImage(ImageData) {\n $scope.contentToShow = \"image\";\n $scope.imageData = ImageData;\n }\n /**\r\n * The function that closes the image and displays the reports again\r\n * @memberof ReportsHistoryCtrl \r\n */\n\n\n function closeImage() {\n $scope.contentToShow = \"reports\";\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('ReportsHistoryFactory', ReportsHistoryFactory);\n /* @ngInject */\n\n function ReportsHistoryFactory($http, apiUrl) {\n /**\r\n * Fetches the ReportIncidents from API\r\n * @memberof ReportsHisReportsHistoryFactorytoryCtrl \r\n */\n function getReportsHistory(reportId, reportType) {\n return $http.get(apiUrl + '/reports/GetHistoryReport?reportId=' + reportId + '&type=' + reportType, {\n 'Content-Type': 'application/json'\n }).then(function (x) {\n return x;\n });\n }\n\n var service = {\n getReportsHistory: getReportsHistory\n };\n return service;\n }\n})();\n\"use strict\";\n\nfunction ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }\n\nfunction _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('RequestFactory', RequestFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name RequestFactory\r\n * @description \r\n * Add & delete requests and get Roster Requests & get ancillaries\r\n * @ngInject\r\n */\n\n function RequestFactory($http, apiUrl, GenericService) {\n /**\r\n * Initialize the CrewAssessment\r\n * @memberof AssessmentSyncResultFactory\r\n */\n function RequestSubmissionDeadline() {\n this.showSubmissionDeadlineModal = false;\n }\n\n var submitResponseObj = {\n success: false,\n message: '',\n data: null\n };\n var objType = 'requestSubmissionEndDates';\n var objCallback = RequestSubmissionDeadline;\n var service = {\n setSubmissionDeadlineDateToStorage: setSubmissionDeadlineDateToStorage,\n getSubmissionDeadlineDateFromStorage: getSubmissionDeadlineDateFromStorage,\n showSubmissionDeadlineModal: showSubmissionDeadlineModal,\n showSubmissionDeadlineAlert: showSubmissionDeadlineAlert,\n updateShowSubmissionDeadlineModal: updateShowSubmissionDeadlineModal,\n getActiveRequests: getActiveRequests,\n getAncillaries: getAncillaries,\n sendFlightRequest: sendFlightRequest,\n sendShiftRequest: sendShiftRequest,\n sendOvernightRequest: sendOvernightRequest,\n sendOtherRequest: sendOtherRequest,\n sendGroundRequest: sendGroundRequest,\n deleteFlightRequest: deleteFlightRequest,\n deleteShiftRequest: deleteShiftRequest,\n deleteOvernightRequest: deleteOvernightRequest,\n deleteOtherRequest: deleteOtherRequest,\n deleteGroundRequest: deleteGroundRequest,\n getPastRequests: getPastRequests\n };\n /**\r\n * Save submission end date of crew member's qualification group to storage\r\n * @param {array} objList A list of Crew Expiries\r\n */\n\n function setSubmissionDeadlineDateToStorage(objList) {\n if (objList != null) {\n var submissionDeadline = {\n submissionEndDate: objList,\n showSubmissionDeadlineModal: true\n };\n GenericService.saveOne(submissionDeadline, objType, objCallback);\n }\n }\n /**\r\n * Calculates days left\r\n * @memberof CalendarCtrl\r\n * @return {string} usage\r\n */\n\n\n function daysDiff(date) {\n var today = moment().startOf('day');\n var expiryDate = moment(date);\n return expiryDate.diff(today, 'days');\n }\n /**\r\n * Get submission end date of crew member's qualification group from storage\r\n */\n\n\n function getSubmissionDeadlineDateFromStorage() {\n return GenericService.getOne(objType, objCallback);\n }\n /**\r\n * Shows submission deadline modal\r\n * @memberof ExpiriesFactory\r\n * @returns {bool} returns the value of showSubmissionDeadlineModal property\r\n */\n\n\n function showSubmissionDeadlineModal() {\n var needsReminder = false;\n var submissionDeadline = getSubmissionDeadlineDateFromStorage();\n\n if (submissionDeadline) {\n var diffDays = daysDiff(submissionDeadline.submissionEndDate);\n\n if (submissionDeadline && submissionDeadline.submissionEndDate && submissionDeadline.showSubmissionDeadlineModal) {\n if (diffDays == 1 || diffDays == -1) {\n needsReminder = true;\n }\n }\n }\n\n return needsReminder;\n }\n /**\r\n * Shows submission deadline alert\r\n * @memberof ExpiriesFactory\r\n * @returns {bool} returns the value of showSubmissionDeadlineAlert property\r\n */\n\n\n function showSubmissionDeadlineAlert() {\n var needsAlert = false;\n var submissionDeadline = getSubmissionDeadlineDateFromStorage();\n\n if (submissionDeadline) {\n var diffDays = daysDiff(submissionDeadline.submissionEndDate);\n\n if (submissionDeadline && submissionDeadline.submissionEndDate) {\n if (diffDays <= 10 && diffDays >= 0) {\n needsAlert = true;\n }\n }\n }\n\n return needsAlert;\n }\n /* Update submissionEndDate modal object to storage\r\n * @memberof RequestFactory\r\n * @param {bool} canShowModal whether the modal can be displayed\r\n */\n\n\n function updateShowSubmissionDeadlineModal(canShowModal) {\n var submissionDeadline = getSubmissionDeadlineDateFromStorage();\n submissionDeadline.showSubmissionDeadlineModal = canShowModal;\n GenericService.saveOne(submissionDeadline, objType, objCallback);\n }\n /**\r\n * Gets all types of the existing requests\r\n */\n\n\n function getActiveRequests() {\n return $http.get(apiUrl + '/RosterRequests/GetRequests', {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getResponse(res);\n })[\"catch\"](function (res) {\n return getResponseFailed(res);\n });\n ;\n }\n /**\r\n * Gets all ancilleries\r\n */\n\n\n function getAncillaries() {\n return $http.get(apiUrl + '/RosterRequests/GetAncillaries', {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getResponse(res);\n })[\"catch\"](function (res) {\n return getResponseFailed(res);\n });\n }\n /**\r\n * Sends the flight request\r\n */\n\n\n function sendFlightRequest(rosterRequest) {\n var requestTimesFixed = _objectSpread({}, rosterRequest);\n\n if (rosterRequest.afterTime) {\n requestTimesFixed.afterTime = rosterRequest.afterTime.clone();\n var startDateObj = new Date(requestTimesFixed.afterTime).fromUTC();\n requestTimesFixed.afterTime = moment(startDateObj);\n } else {\n requestTimesFixed.afterTime = null;\n }\n\n if (rosterRequest.beforeTime) {\n requestTimesFixed.beforeTime = rosterRequest.beforeTime.clone();\n var endDateObj = new Date(requestTimesFixed.beforeTime).fromUTC();\n requestTimesFixed.beforeTime = moment(endDateObj);\n } else {\n requestTimesFixed.beforeTime = null;\n }\n\n var rosterRequestsURL = apiUrl + '/RosterRequests/FlightRequestInsert';\n return $http.post(rosterRequestsURL, requestTimesFixed, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getCreateRequestResponse(res);\n })[\"catch\"](function (res) {\n return getResponseFailed(res);\n });\n }\n /**\r\n * Sends the shift request\r\n */\n\n\n function sendShiftRequest(rosterRequest) {\n var rosterRequestsURL = apiUrl + '/RosterRequests/ShiftTimeRequestInsert';\n return $http.post(rosterRequestsURL, rosterRequest, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getCreateRequestResponse(res);\n })[\"catch\"](function (res) {\n return getResponseFailed(res);\n });\n }\n /**\r\n * Sends the overnight request\r\n */\n\n\n function sendOvernightRequest(rosterRequest) {\n var rosterRequestsURL = apiUrl + '/RosterRequests/OvernightsRequestInsert';\n return $http.post(rosterRequestsURL, rosterRequest, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getCreateRequestResponse(res);\n })[\"catch\"](function (res) {\n return getResponseFailed(res);\n });\n }\n /**\r\n * Sends the other request\r\n */\n\n\n function sendOtherRequest(rosterRequest) {\n var rosterRequestsURL = apiUrl + '/RosterRequests/OtherRequestInsert';\n return $http.post(rosterRequestsURL, rosterRequest, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getCreateRequestResponse(res);\n })[\"catch\"](function (res) {\n return getResponseFailed(res);\n });\n }\n /**\r\n * Sends the ground request\r\n */\n\n\n function sendGroundRequest(rosterRequest) {\n var rosterRequestsURL = apiUrl + '/RosterRequests/GroundDutyRequestInsert';\n return $http.post(rosterRequestsURL, rosterRequest, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getCreateRequestResponse(res);\n })[\"catch\"](function (res) {\n return getResponseFailed(res);\n });\n }\n /**\r\n * Gets the response message\r\n */\n\n\n function getResponse(res) {\n submitResponseObj.success = res.data.success;\n\n if (res.data.success) {\n submitResponseObj.message = \"Data retrieved successfully\";\n submitResponseObj.data = res.data.data;\n } else {\n submitResponseObj.message = res.data.errorMessage;\n }\n\n return submitResponseObj;\n }\n /**\r\n * Gets the creation response message\r\n */\n\n\n function getCreateRequestResponse(res) {\n submitResponseObj.success = res.data.success;\n\n if (res.data.success) {\n submitResponseObj.message = \"Request submited successfully\";\n submitResponseObj.data = res.data.data;\n } else {\n submitResponseObj.message = res.data.errorMessage;\n }\n\n return submitResponseObj;\n }\n /**\r\n * Gets the response failure message\r\n */\n\n\n function getResponseFailed(res) {\n submitResponseObj.success = false;\n submitResponseObj.message = \"Something went wrong!\";\n return submitResponseObj;\n }\n /**\r\n * Deletes the flight request\r\n */\n\n\n function deleteFlightRequest(requestId) {\n var deleteRequestsURL = apiUrl + '/RosterRequests/FlightRequestDelete';\n return $http.post(deleteRequestsURL, requestId, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getCreateRequestResponse(res);\n });\n }\n /**\r\n * Deletes the shift request\r\n */\n\n\n function deleteShiftRequest(requestId) {\n var deleteRequestsURL = apiUrl + '/RosterRequests/ShiftTimeRequestDelete';\n return $http.post(deleteRequestsURL, requestId, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getCreateRequestResponse(res);\n });\n }\n /**\r\n * Deletes the overnight request\r\n */\n\n\n function deleteOvernightRequest(requestId) {\n var deleteRequestsURL = apiUrl + '/RosterRequests/OvernightsRequestDelete';\n return $http.post(deleteRequestsURL, requestId, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getCreateRequestResponse(res);\n });\n }\n /**\r\n * Deletes the other request\r\n */\n\n\n function deleteOtherRequest(requestId) {\n var deleteRequestsURL = apiUrl + '/RosterRequests/OtherRequestDelete';\n return $http.post(deleteRequestsURL, requestId, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getCreateRequestResponse(res);\n });\n }\n /**\r\n * Deletes the ground request\r\n */\n\n\n function deleteGroundRequest(requestId) {\n var deleteRequestsURL = apiUrl + '/RosterRequests/GroundDutyRequestDelete';\n return $http.post(deleteRequestsURL, requestId, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getCreateRequestResponse(res);\n });\n }\n /**\r\n * Gets all types of the past requests\r\n */\n\n\n function getPastRequests() {\n return $http.get(apiUrl + '/RosterRequests/GetPastRequests', {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getResponse(res);\n })[\"catch\"](function (res) {\n return getResponseFailed(res);\n });\n ;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('requestForm', requestForm);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name requestForm\r\n * @restrict E\r\n * @description\r\n * Crew Table with a double row per crew member\r\n * @example\r\n * Usage:\r\n * \r\n * \r\n * @ngInject\r\n */\n\n function requestForm() {\n function link(scope, attrs) {}\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/RosterRequests/requestForm.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('RequestInstructionsCtrl', RequestInstructionsCtrl);\n /**\r\n * @memberof PilotReports\r\n * @ngdoc controller\r\n * @name RequestInstructionsCtrl\r\n * @description \r\n * Get the Roster Request Instructions\r\n * @ngInject\r\n */\n\n function RequestInstructionsCtrl($scope, $uibModalInstance) {\n $scope.page = 1;\n $scope.cancel = cancel;\n $scope.nextPage = nextPage;\n $scope.previousPage = previousPage;\n $scope.instructionPages = 1;\n /**\r\n * Goes to the next page of leave instructions\r\n * @memberof RequestInstructionsCtrl\r\n */\n\n function nextPage() {\n $scope.page = $scope.page + 1;\n normalizePage();\n }\n /**\r\n * Goes to the previous page of leave instructions\r\n * @memberof RequestInstructionsCtrl\r\n */\n\n\n function previousPage() {\n $scope.page = $scope.page - 1;\n normalizePage();\n }\n /**\r\n * Normalize the page number if it is out of range\r\n * @memberof RequestInstructionsCtrl\r\n */\n\n\n function normalizePage() {\n if ($scope.page > $scope.instructionPages || $scope.page < 1) {\n $scope.page = 1;\n }\n }\n /**\r\n * Close the modal\r\n * @memberof RequestInstructionsCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close('close');\n }\n\n ;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('requestItem', requestItem);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name requestItem\r\n * @restrict E\r\n * @description\r\n * Request info\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function requestItem($uibModal, RequestFactory) {\n function link(scope, element, attrs) {\n //scope.request\n scope.loading = false;\n scope.errorMessage = null;\n scope.contents = {\n showPendingIcon: false,\n //sholwAcknowledgedIcon: false,\n showAcceptedIcon: false,\n showRejectedIcon: false,\n showFullRequestComment: false,\n showFullRejectComment: false,\n rejectReason: \"\",\n infoMessage: \"\",\n loading: false,\n showErrorMessage: false,\n errorMessage: \"\",\n textclass: \"\"\n };\n scope.confirmCancelRequest = confirmCancelRequest;\n scope.toggleFullCommentVisibility = toggleFullCommentVisibility;\n scope.toggleFullRejectCommentVisibility = toggleFullRejectCommentVisibility;\n scope.todayDate = moment().format('DD/MM');\n getFlightDescription();\n\n function getFlightDescription() {\n scope.request.FlightDescription = null;\n\n if (scope.request.FlightNo) {\n scope.request.FlightDescription = scope.request.FlightNo;\n } else if (scope.request.FlightDutyCategory) {\n scope.request.FlightDescription = scope.request.FlightDutyCategory;\n } else if (scope.request.AfterTime && scope.request.BeforeTime) {\n scope.request.FlightDescription = moment.utc(scope.request.AfterTime).format('HH:mm') + \" - \" + moment.utc(scope.request.BeforeTime).format('HH:mm');\n } else if (scope.request.AfterTime) {\n scope.request.FlightDescription = \"after \" + moment.utc(scope.request.AfterTime).format('HH:mm');\n } else if (scope.request.BeforeTime) {\n scope.request.FlightDescription = \"till \" + moment.utc(scope.request.BeforeTime).format('HH:mm');\n }\n } //Toggles comments\n\n\n function toggleFullCommentVisibility() {\n scope.contents.showFullRequestComment = !scope.contents.showFullRequestComment;\n }\n\n function toggleFullRejectCommentVisibility() {\n scope.contents.showFullRejectComment = !scope.contents.showFullRejectComment;\n }\n\n getContents(); //update contents obj:\n\n function getContents() {\n if (scope.request.StatusText == \"FinalAccepted\") {\n scope.contents.textclass = \"text-green\";\n scope.contents.showAcceptedIcon = true;\n scope.contents.infoMessage = \"your request has been accepted!\";\n } else if (scope.request.StatusText == \"Accepted\") {\n scope.contents.textclass = \"text-indigo\";\n scope.contents.showPendingIcon = true;\n scope.contents.infoMessage = \"your request is under review!\";\n } else if (scope.request.StatusText == \"Pending\") {\n scope.contents.textclass = \"text-light-blue\";\n scope.contents.showPendingIcon = true;\n scope.contents.infoMessage = \"your request is pending!\";\n } else if (scope.request.StatusText == \"Acknowledged\") {\n scope.contents.textclass = \"text-light-blue\";\n scope.contents.showPendingIcon = true;\n scope.contents.infoMessage = \"your request is under review!\";\n } else if (scope.request.StatusText == \"Rejected\") {\n scope.contents.rejectReason = scope.rejectReason;\n scope.contents.textclass = \"text-red\";\n scope.contents.showRejectedIcon = true;\n scope.contents.infoMessage = \"your request has been rejected!\";\n }\n }\n /**\r\n * Opens confirmation modal for the request cancel action\r\n * @memberof request\r\n */\n\n\n function confirmCancelRequest() {\n bootbox.dialog({\n message: \"You are about to cancel your request. Are you sure?

\",\n title: \"Caution!\",\n buttons: {\n confirm: {\n label: 'Confirm',\n className: \"btn-danger\",\n callback: function callback() {\n cancelRequest();\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n\n function cancelRequest() {\n scope.contents.loading = true;\n\n if (scope.requestType == \"Flight\") {\n RequestFactory.deleteFlightRequest(scope.request.Id).then(function (res) {\n handleDeleteResponse(res);\n })[\"catch\"](function () {\n handleErrorResponse();\n });\n } else if (scope.requestType == \"Ground\") {\n RequestFactory.deleteGroundRequest(scope.request.Id).then(function (res) {\n handleDeleteResponse(res);\n })[\"catch\"](function () {\n handleErrorResponse();\n });\n } else if (scope.requestType == \"ShiftTime\") {\n RequestFactory.deleteShiftRequest(scope.request.Id).then(function (res) {\n handleDeleteResponse(res);\n })[\"catch\"](function () {\n handleErrorResponse();\n });\n } else if (scope.requestType == \"Overnight\") {\n RequestFactory.deleteOvernightRequest(scope.request.Id).then(function (res) {\n handleDeleteResponse(res);\n })[\"catch\"](function () {\n handleErrorResponse();\n });\n } else if (scope.requestType == \"Other\") {\n RequestFactory.deleteOtherRequest(scope.request.Id).then(function (res) {\n handleDeleteResponse(res);\n })[\"catch\"](function () {\n handleErrorResponse();\n });\n }\n }\n\n function handleDeleteResponse(res) {\n scope.contents.loading = false;\n\n if (res.success == true) {\n scope.refreshRequests();\n } else {\n scope.contents.showErrorMessage = true;\n scope.contents.errorMessage = \"Cancel request failed.\";\n }\n }\n\n function handleErrorResponse() {\n scope.contents.loading = false;\n scope.contents.showErrorMessage = true;\n scope.contents.errorMessage = \"Cancel request failed.\";\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/RosterRequests/requestItem.tpl.html',\n scope: {\n request: '=',\n requestType: \"@\",\n rejectReason: \"@\",\n refreshRequests: \"&\",\n isHistoryView: '@'\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('RequestsCtrl', RequestsCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name RequestsCtrl\r\n * @description \r\n * Shows Roster Requests\r\n * @ngInject\r\n */\n\n function RequestsCtrl($scope, RequestFactory, $timeout, $uibModal, LogService) {\n $scope.state = 'requests';\n $scope.ancillaries = null;\n $scope.activeRequests = null;\n $scope.isAvailableFeature = false;\n $scope.hasAncillaries = false; //for testing true || live false !;\n\n $scope.showActiveRequests = false; //for testing true || live false !;\n\n $scope.contentToShow = \"loading\";\n window.addEventListener('online', function (e) {\n $timeout(checkConnectionStatus());\n });\n $scope.init = checkConnectionStatus();\n $scope.closeAlert = closeAlert;\n $scope.openRequest = openRequest;\n $scope.page = null;\n $scope.closeForm = closeForm;\n $scope.newForm = {};\n $scope.submitRequest = submitRequest;\n $scope.submitForcedRequest = submitForcedRequest;\n $scope.forceSubmitRequest = forceSubmitRequest;\n $scope.getActiveRequests = getActiveRequests;\n $scope.updateFromValue = updateFromValue;\n $scope.dutyCode = \"\";\n $scope.showHelp = showHelp;\n $scope.instruction = '';\n $scope.flightRequestType = null;\n $scope.setFlightRequestType = setFlightRequestType;\n $scope.resetStart = resetStart;\n $scope.resetEnd = resetEnd; //ground duties request types:\n\n $scope.singleDayRequestType = true;\n $scope.toggleGroundRequestType = toggleGroundRequestType;\n $scope.updateFromValueGD = updateFromValueGD;\n $scope.submitLoader = false;\n $scope.toggleViewMode = toggleViewMode;\n $scope.getPastRequests = getPastRequests;\n $scope.isHistoryView = false;\n $scope.showPastRequests = false;\n $scope.hasDutyPreferencesSettings = false; //------------ Request List --------------\n // $scope.showMobileRequestListCriteria = true;\n\n $scope.filterRequest = filterRequest;\n $scope.getRequestBorderStyle = getRequestBorderStyle;\n $scope.getRejectReason = getRejectReason;\n $scope.toggle = {\n Accepted: true,\n Rejected: true,\n Pending: true,\n FinalAccepted: true\n };\n $scope.submissionDeadline = RequestFactory.getSubmissionDeadlineDateFromStorage();\n $scope.daysDiff = daysDiff;\n /**\r\n * Calculates days left\r\n * @memberof CalendarCtrl\r\n * @return {string} usage\r\n */\n\n function daysDiff(date) {\n var today = moment().startOf('day');\n var expiryDate = moment(date);\n return expiryDate.diff(today, 'days');\n }\n /**\r\n * Get ancillaries for the forms\r\n * @memberof RequestsCtrl \r\n */\n\n\n function getAncillaries() {\n RequestFactory.getAncillaries().then(function (response) {\n $scope.contentToShow = \"\";\n\n if (response.success) {\n if (response.data) {\n $scope.ancillaries = response.data; // Request types based on crew member's qualification group(s) settings\n\n $scope.hasDutyPreferencesSettings = $scope.ancillaries.ShiftTimeRequests && $scope.ancillaries.ShiftTimeRequests.length > 0;\n $scope.hasOtherRequestsSettings = $scope.ancillaries.HasOtherRequestsSettings;\n $scope.hasFlightRequestsByFlightNoSettings = $scope.ancillaries.HasFlightRequestsByFlightNoSettings;\n $scope.hasFlightRequestsByTimeRangesSettings = $scope.ancillaries.HasFlightRequestsByTimeRangesSettings;\n $scope.flightOrDutyPreferenceIsVisible = $scope.ancillaries.FlightDutyCategories && $scope.ancillaries.FlightDutyCategories.length > 0 || $scope.hasFlightRequestsByFlightNoSettings || $scope.hasFlightRequestsByTimeRangesSettings; // Create Your Request Menu: visibility option \n\n $scope.isAvailableFeature = $scope.ancillaries.DutyCodes && $scope.ancillaries.DutyCodes.length > 0 || $scope.flightOrDutyPreferenceIsVisible || $scope.hasDutyPreferencesSettings || $scope.hasOtherRequestsSettings;\n $scope.hasAncillaries = true;\n $scope.newForm.singleDate = $scope.ancillaries.RosterPeriodFrom;\n $scope.newForm.dateFrom = $scope.ancillaries.RosterPeriodFrom;\n $scope.newForm.dateTo = $scope.ancillaries.RosterPeriodTo; //groundDuties\n\n $scope.newForm.dutyDateFrom = $scope.ancillaries.RosterPeriodFrom;\n $scope.newForm.dutyDateTo = $scope.ancillaries.RosterPeriodFrom;\n $scope.optionsSingle = {\n minDate: $scope.ancillaries.RosterPeriodFrom,\n initDate: $scope.ancillaries.RosterPeriodFrom\n };\n $scope.optionsFrom = {\n minDate: $scope.ancillaries.RosterPeriodFrom,\n initDate: $scope.ancillaries.RosterPeriodFrom\n };\n $scope.optionsTo = {\n minDate: $scope.ancillaries.RosterPeriodFrom,\n initDate: $scope.ancillaries.RosterPeriodTo\n };\n $scope.optionsDutyDateTo = {\n minDate: $scope.ancillaries.RosterPeriodFrom,\n initDate: $scope.ancillaries.RosterPeriodFrom\n }; // Fetch flight category types for the dropdown list\n\n $scope.ancillaries.flightCategoryTypes = [];\n\n if ($scope.hasFlightRequestsByFlightNoSettings) {\n $scope.ancillaries.flightCategoryTypes.push({\n Value: 1,\n Text: 'Flight No.'\n });\n }\n\n if ($scope.ancillaries.FlightDutyCategories && $scope.ancillaries.FlightDutyCategories.length > 0) {\n $scope.ancillaries.flightCategoryTypes.push({\n Value: 2,\n Text: 'Flight Duty Preference'\n });\n }\n\n if ($scope.hasFlightRequestsByTimeRangesSettings) {\n $scope.ancillaries.flightCategoryTypes.push({\n Value: 3,\n Text: 'Flight Duty Preference with time limit'\n });\n }\n } else {\n //TODO:: fix message\n showError(\"Ancillaries not found.\");\n }\n } else {\n showError(response.message);\n }\n });\n }\n /**\r\n * Get Active Requests\r\n * @memberof RequestsCtrl \r\n */\n\n\n function getActiveRequests() {\n RequestFactory.getActiveRequests().then(function (response) {\n if (response.success) {\n if (response.data) {\n $scope.activeRequests = response.data;\n $scope.instruction = response.data.QualificationGroupInstruction;\n $scope.showActiveRequests = response.data.FlightRequests.length || response.data.GroundDutyRequests.length || response.data.OtherRequests.length || response.data.OvernightsRequests.length || response.data.ShiftTimeRequests.length;\n } else {\n showError(\"Something went wrong while fetching your roster requests.\");\n }\n } else {\n showError(response.message);\n }\n });\n }\n\n function getPastRequests() {\n RequestFactory.getPastRequests().then(function (response) {\n if (response.success) {\n if (response.data) {\n $scope.pastRequests = response.data;\n $scope.isHistoryView = true;\n $scope.instruction = response.data.QualificationGroupInstruction;\n $scope.showPastRequests = response.data.FlightRequests.length > 0 || response.data.GroundDutyRequests.length > 0 || response.data.OtherRequests.length > 0 || response.data.OvernightsRequests.length > 0 || response.data.ShiftTimeRequests.length > 0;\n } else {\n showError(\"Something went wrong while fetching your roster requests.\");\n }\n } else {\n showError(response.message);\n }\n });\n }\n /**\r\n * Displays the error message\r\n * @memberof RequestsCtrl \r\n * @param {string} message message to display\r\n */\n\n\n function showError(message) {\n $scope.contentToShow = \"error\";\n $scope.errorMessage = message;\n }\n /**\r\n * Displays the success message\r\n * @memberof RequestsCtrl\r\n */\n\n\n function showSuccess(message) {\n $scope.contentToShow = \"success\";\n $scope.successMessage = message;\n }\n\n function closeAlert() {\n $scope.contentToShow = \"\";\n }\n /**\r\n * Checks if the client is online or offline \r\n * @memberof RequestsCtrl \r\n */\n\n\n function checkConnectionStatus() {\n var isOnline = window.navigator.onLine;\n\n if (isOnline) {\n getAncillaries();\n getActiveRequests();\n } else {\n showError(\"Please check your internet connection!\");\n }\n }\n /**\r\n * Date to always greater than date from\r\n * @memberof RequestsCtrl \r\n */\n\n\n function updateFromValue(dateFrom) {\n $scope.newForm.dateTo = dateFrom;\n $scope.optionsTo = {\n minDate: dateFrom\n };\n }\n /**\r\n * Date picker limits for the ground duty requests\r\n * @memberof RequestsCtrl \r\n */\n\n\n function updateFromValueGD(dateFrom, limitation) {\n $scope.newForm.dateTo = dateFrom;\n $scope.optionsDutyDateTo = {\n initDate: dateFrom,\n minDate: dateFrom,\n maxDate: dateFrom.AddDays(limitation - 1)\n };\n }\n\n function setFlightRequestType() {\n //[{Value: 1, Text:'Flight No.'}, {Value: 2, Text:'Flight Duty Preference'}, {Value: 3, Text:'Time Limitations'}]\n //$scope.flightRequestType = parseInt($scope.newForm.flightRequestType, 10);\n if ($scope.newForm.flightRequestType != null) {\n $scope.flightRequestType = parseInt($scope.newForm.flightRequestType, 10);\n } else {\n $scope.flightRequestType = null;\n }\n }\n\n function resetStart() {\n $scope.newForm.afterTime = null;\n }\n\n function resetEnd() {\n $scope.newForm.beforeTime = null;\n }\n\n function toggleGroundRequestType() {\n if ($scope.newForm.groundRequestType == 'continuous') {\n $scope.singleDayRequestType = false;\n } else {\n $scope.singleDayRequestType = true;\n }\n }\n /**\r\n * Opens the request type selected\r\n * @memberof RequestsCtrl\r\n */\n\n\n function openRequest(inputObject, dutyCode) {\n clearForms();\n\n if (inputObject == \"Flight\") {\n $scope.page = 'Flight';\n } else if (inputObject == \"Duty Preference\") {\n $scope.page = 'Duty Preference';\n } else if (inputObject == \"Overnight\") {\n $scope.page = 'Overnight';\n } else if (inputObject == \"Other\") {\n $scope.page = 'Other';\n } else if (inputObject == \"Ground Duty\") {\n $scope.page = 'Ground Duty';\n $scope.dutyCode = dutyCode;\n }\n }\n /**\r\n * Submits the request form\r\n * @memberof RequestsCtrl\r\n */\n\n\n function submitRequest(inputObject, dutyCode) {\n $scope.submitLoader = true;\n\n if (inputObject == \"Flight\" && $scope.flightRequestType != null) {\n var rosterRequest = {\n FlightDate: $scope.newForm.singleDate.toString(\"yyyy/MM/dd\"),\n ReasonId: $scope.newForm.requestReason.Id,\n Comments: $scope.newForm.comments,\n Type: $scope.flightRequestType,\n IsForced: false\n };\n\n if ($scope.flightRequestType == 1) {\n rosterRequest.FlightNo = $scope.newForm.flightNo;\n } else if ($scope.flightRequestType == 2) {\n rosterRequest.FlightDutyCategoryId = $scope.newForm.flightDuty.Id;\n } else if ($scope.flightRequestType == 3) {\n rosterRequest.afterTime = $scope.newForm.afterTime !== null && $scope.newForm.afterTime !== undefined ? moment($scope.newForm.afterTime) : null;\n rosterRequest.beforeTime = $scope.newForm.beforeTime !== null && $scope.newForm.beforeTime !== undefined ? moment($scope.newForm.beforeTime) : null;\n }\n\n RequestFactory.sendFlightRequest(rosterRequest).then(function (response) {\n handleSubmitResponse(response, rosterRequest);\n });\n } else if (inputObject == \"Ground Duty\") {\n //validation with duty limitation\n var trimmedFrom = new Date($scope.newForm.dateFrom);\n var trimmedTo = new Date($scope.newForm.dateTo);\n var diffDays = Date.DifferenceInDays(trimmedFrom.trimTime(), trimmedTo.trimTime());\n\n if (diffDays > dutyCode.Limitation) {\n //show warning message? : \n $scope.disableSubmit = true;\n }\n\n if ($scope.singleDayRequestType) {\n $scope.newForm.dateTo = $scope.newForm.dateFrom;\n }\n\n var rosterRequest = {\n DutyDateFrom: $scope.newForm.dateFrom.toString(\"yyyy/MM/dd\"),\n DutyDateTo: $scope.newForm.dateTo.toString(\"yyyy/MM/dd\"),\n GroundDuty: dutyCode.Code,\n ReasonId: $scope.newForm.requestReason.Id,\n Comments: $scope.newForm.comments,\n IsForced: false\n };\n RequestFactory.sendGroundRequest(rosterRequest).then(function (response) {\n handleSubmitResponse(response, rosterRequest);\n });\n } else if (inputObject == \"Duty Preference\") {\n var rosterRequest = {\n DateFrom: $scope.newForm.dateFrom.toString(\"yyyy/MM/dd\"),\n DateTo: $scope.newForm.dateTo.toString(\"yyyy/MM/dd\"),\n ShiftTimeId: $scope.newForm.shiftTime.Id,\n ReasonId: $scope.newForm.requestReason.Id,\n Comments: $scope.newForm.comments\n };\n RequestFactory.sendShiftRequest(rosterRequest).then(function (response) {\n handleSubmitResponse(response);\n });\n } else if (inputObject == \"Overnight\") {\n var rosterRequest = {\n DateFrom: $scope.newForm.dateFrom.toString(\"yyyy/MM/dd\"),\n DateTo: $scope.newForm.dateTo.toString(\"yyyy/MM/dd\"),\n Minimum: $scope.newForm.minOvernight,\n Maximum: $scope.newForm.maxOvernight,\n ReasonId: $scope.newForm.requestReason.Id,\n Comments: $scope.newForm.comments\n };\n RequestFactory.sendOvernightRequest(rosterRequest).then(function (response) {\n handleSubmitResponse(response);\n });\n } else if (inputObject == \"Other\") {\n var rosterRequest = {\n DateFrom: $scope.newForm.dateFrom.toString(\"yyyy/MM/dd\"),\n DateTo: $scope.newForm.dateTo.toString(\"yyyy/MM/dd\"),\n ReasonId: $scope.newForm.requestReason.Id,\n RequestFreeText: $scope.newForm.otherComments\n };\n RequestFactory.sendOtherRequest(rosterRequest).then(function (response) {\n handleSubmitResponse(response);\n });\n }\n }\n /**\r\n * Handles the response from the API\r\n * @memberof RequestsCtrl \r\n * @param {object} response the response object from API\r\n */\n\n\n function handleSubmitResponse(response, rosterRequest) {\n var responseData = null;\n\n if (response.data) {\n if (typeof response.data === 'string') {\n try {\n responseData = JSON.parse(response.data);\n } catch (error) {\n LogService.error(error, 'Failed to parse JSON');\n }\n } else {\n responseData = response.data;\n }\n }\n\n if (rosterRequest && response.success == true && responseData && responseData.success == false) {\n if (responseData.isOverlappingDuty) {\n //bootbox for the overlap warning\n showOverlappingMessage();\n } else if (responseData.periodNotFound) {\n showPeriodNotFoundMessage();\n } else if ($scope.page == \"Ground Duty\" || $scope.page == \"Flight\") {\n //bootbox to confirm the forced submit - new submit on confirmed\n forceSubmitRequest(rosterRequest, $scope.page, responseData);\n } else {\n //show error message\n showError('Request submission failed.');\n }\n } else if (response.success == false) {\n //show error message\n showError(response.message);\n } else if (responseData.success == false) {\n //show error message\n showError('Request submission failed.');\n } else {\n //show success message\n showSuccess(\"Request submited successfully.\"); //refresh request list!\n\n getActiveRequests();\n }\n\n closeForm();\n }\n /**\r\n * Clears forms\r\n * @memberof RequestsCtrl\r\n */\n\n\n function clearForms() {\n $scope.newForm = {};\n\n if ($scope.ancillaries) {\n $scope.newForm.singleDate = $scope.ancillaries.RosterPeriodFrom;\n $scope.newForm.dateFrom = $scope.ancillaries.RosterPeriodFrom;\n $scope.newForm.dateTo = $scope.ancillaries.RosterPeriodTo;\n $scope.singleDayRequestType = true;\n $scope.submitLoader = false;\n $scope.disableSubmit = false;\n }\n }\n /**\r\n * Closes forms\r\n * @memberof RequestsCtrl\r\n */\n\n\n function closeForm() {\n clearForms();\n $scope.page = null;\n }\n /**\r\n * Opens confirmation modal when request is submitted\r\n * @memberof RequestsCtrl\r\n */\n\n\n function forceSubmitRequest(rosterRequest, type, responseData) {\n var rosterPeriodFrom = moment.utc(responseData.rosterPeriodFrom).format('D MMM YYYY');\n var rosterPeriodTo = moment.utc(responseData.rosterPeriodTo).format('D MMM YYYY');\n var title = \"Warning!\";\n console.log(rosterRequest);\n var message = \"\";\n\n if (responseData.limitationReached) {\n message = message + \"You have exceeded the maximum number of Requests \" + \"(\" + responseData.activeRequests + \"/\" + responseData.maxLimit + \")\" + \" for this Roster Period \" + \"(\" + rosterPeriodFrom + \" to \" + rosterPeriodTo + \").\" + \"
\";\n }\n\n if (responseData.isOverdue == true) {\n message = message + \"The Deadline to submit requests for this Roster Period \" + \"(\" + rosterPeriodFrom + \" to \" + rosterPeriodTo + \") has passed.

\";\n }\n\n if (type == \"Ground Duty\" && responseData.hasDailyLimitation == true) {\n message = message + \"The selected date \" + rosterRequest.DutyDate + \" has limited Availability. The probability to get your request is low.
\";\n }\n\n if (type == \"Ground Duty\" && responseData.weekendRequestsLimitReached == true) {\n message = message + \"You have exceeded the allowed number of Weekends Requests for this Roster Period \" + \"(\" + rosterPeriodFrom + \" to \" + rosterPeriodTo + \").

\";\n }\n\n message = message + \" Your request will be ignored by the system. Do you want to send it for Managment Approval?
\";\n bootbox.dialog({\n message: message,\n title: title,\n buttons: {\n confirm: {\n label: 'Confirm',\n className: \"btn-success\",\n callback: function callback() {\n submitForcedRequest(rosterRequest, type);\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n /**\r\n * Opens a modal with overlapping message\r\n * @memberof RequestsCtrl\r\n */\n\n\n function showOverlappingMessage() {\n var title = \"Warning!\";\n var message = \"You cannot submit 2 requests for the same date.
\";\n bootbox.dialog({\n message: message,\n title: title,\n buttons: {\n cancel: {\n label: \"Close\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n /**\r\n * Opens a modal with overlapping message\r\n * @memberof RequestsCtrl\r\n */\n\n\n function showPeriodNotFoundMessage() {\n var title = \"Warning!\";\n var message = \"You cannot send request for this roster period.
\";\n bootbox.dialog({\n message: message,\n title: title,\n buttons: {\n cancel: {\n label: \"Close\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n /**\r\n * Submits the forced request\r\n * @memberof RequestsCtrl\r\n */\n\n\n function submitForcedRequest(rosterRequest, type) {\n if (type == \"Flight\") {\n rosterRequest.IsForced = true;\n RequestFactory.sendFlightRequest(rosterRequest).then(function (response) {\n handleSubmitResponse(response);\n });\n } else if (type == \"Ground Duty\") {\n rosterRequest.IsForced = true;\n RequestFactory.sendGroundRequest(rosterRequest).then(function (response) {\n handleSubmitResponse(response);\n });\n }\n }\n\n function getRejectReason(rejectReasonId) {\n var reasonText = \"\";\n\n if (rejectReasonId && $scope.ancillaries) {\n var rejectReason = $scope.ancillaries.RejectReasons.find(function (f) {\n return f.Id == rejectReasonId;\n });\n\n if (rejectReason) {\n reasonText = rejectReason.Text;\n }\n }\n\n return reasonText;\n }\n\n function filterRequest(request) {\n var isShown = false;\n\n if (request.Id > 0) {\n if (request.StatusText == \"FinalAccepted\" && $scope.toggle.FinalAccepted) {\n isShown = true;\n } else if ((request.ValidationStatusText == \"Validated\" && request.StatusText != \"FinalAccepted\" || request.StatusText == \"Accepted\" || request.StatusText == \"Acknowledged\") && $scope.toggle.Accepted) {\n isShown = true;\n } else if (request.StatusText == \"Pending\" && $scope.toggle.Pending) {\n isShown = true;\n } else if (request.StatusText == \"Rejected\" && $scope.toggle.Rejected) {\n isShown = true;\n }\n }\n\n return isShown;\n }\n\n function getRequestBorderStyle(request) {\n var textclass = \"\";\n\n if (request.StatusText == \"FinalAccepted\") {\n textclass = \"border-left-green\";\n } else if (request.StatusText == \"Accepted\") {\n textclass = \"border-left-indigo\";\n } else if (request.StatusText == \"Pending\" || request.StatusText == \"Acknowledged\") {\n textclass = \"border-left-light-blue\";\n } else if (request.StatusText == \"Rejected\") {\n textclass = \"border-left-red\";\n } else {\n textclass = \"border-left-blue-gray\";\n }\n\n return textclass;\n }\n\n function showHelp() {\n $uibModal.open({\n templateUrl: 'views/RosterRequests/dlgRequestInstructions.html',\n controller: 'RequestInstructionsCtrl',\n size: 'lg',\n scope: $scope,\n backdrop: 'static',\n keyboard: false,\n resolve: {}\n });\n }\n\n function toggleViewMode(elem, className) {\n $('body').find('div#' + elem + ' > div').not('.tip').hide(\"slow\");\n $('body').find('div#' + elem + ' div.' + className).not('.tip').show(\"slow\");\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('FatigueCtrl', FatigueCtrl);\n\n function FatigueCtrl($scope, $routeParams, FlightFactory, $location, SafetyReportFactory, $timeout) {\n var flightId = $routeParams.flightId;\n var flight = FlightFactory.getFlightFromStorage(flightId);\n $scope.flight = flight;\n $scope.responseMessage = \"\";\n $scope.showPanel = \"submit\";\n $scope.operationalPhasesOptions = ['Parked', 'Pushback', 'Taxi-Out', 'Take-Off', 'Climb', 'Cruise', 'Descent', 'Approach', 'Landing', 'Taxi-In'];\n $scope.rateFeltOptions = ['Fully Alert - wide awake', 'Very Lively - responsive, but not at peak', 'OK - somewhat fresh', 'A Little Tired - less than fresh', 'Moderately Tired - let down'];\n $scope.signsPhysicalOptions = ['No physical signs noted ', 'Fidgeting', 'Rubbing eyes', 'Heavy eyelids', 'Yawning', 'Frequent blinking', 'Staring blankly', 'Long blinks', 'Difficulty keeping eyes open', 'Head nodding', 'Micro-sleeps', 'Unintentional sleeps'];\n $scope.signsCognitiveOptions = ['No cognitive signs noted', 'Impaired attention', 'Difficulty concentrating', 'Impaired memory', 'Reduced communication', 'Impaired problem solving', 'Increased risk taking', 'Impaired situational awareness', 'Accidentally doing the wrong thing (error)', 'Accidentally not doing the right thing (omission)', 'Failure to anticipate the event or action'];\n $scope.signsEmotionalOptions = ['No emotional signs', 'More quiet or withdrawn than usual', 'Lacking in energy', 'Lacking in motivation to do the task well', 'Negative mood', 'Irritable or grumpy behavior'];\n $scope.counterMeasuresOptions = ['Controlled rest', 'Caffeine', 'Use of automationy', 'Change of controls', 'Turn up the lights', 'Food, drink', 'Increased checks', 'Workload share', 'Increased communication', 'Inform a colleague'];\n $scope.hours24Options = Array.from({\n length: 21\n }, function (_, i) {\n return i;\n }); // Generates an array with values from 0 to 20\n\n $scope.hoursAwakeOptions = Array.from({\n length: 21\n }, function (_, i) {\n return i;\n }); // Generates an array with values from 0 to 20\n\n $scope.formData = {\n flightId: $routeParams.flightId,\n flightNo: flight.FlightNo,\n flightDate: flight.ScheduledDeparture,\n flightDep: flight.Departure,\n flightArr: flight.Arrival,\n flightRegistration: flight.AcTailNo,\n occurenceTitle: \"\",\n description: \"\",\n // attachedFiles: [],\n operationalPhase: \"\",\n rateFelt: \"\",\n signsPhysical: [],\n signsCognitive: [],\n signsEmotional: [],\n hours24: \"\",\n hoursAwake: \"\",\n rateFeltSecond: \"\",\n counterMeasures: []\n };\n\n $scope.toggleSelection = function (option, signs) {\n var idx = signs.indexOf(option);\n\n if (idx > -1) {\n signs.splice(idx, 1);\n } else {\n signs.push(option);\n }\n };\n\n $scope.isChecked = function (option, signs) {\n return signs.indexOf(option) > -1;\n };\n\n $scope.getSelectedOptionsText = function (signs) {\n if (signs.length === 0) {\n return \"- Select options -\";\n }\n\n return signs.join(', ');\n };\n\n $scope.isRequiredFieldEmpty = function (field) {\n return !field.length;\n };\n\n $scope.sizeLimitKb = 25000;\n $scope.fileTooLargeMsg = false;\n $scope.confirmCreateFatigueReport = confirmCreateFatigueReport;\n $scope.fileUploaded = fileUploaded;\n $scope.removeFile = removeFile;\n $scope.isIFileTooLarge = isFileTooLarge;\n $scope.submitFatigueReport = submitFatigueReport;\n $scope.sendFatigueReport = sendFatigueReport;\n $scope.submitted = false;\n\n function gotoFlightInfo(flightId) {\n $location.path('/flightinfo/' + flightId);\n }\n\n function submitFatigueReport() {\n if ($scope.fatigueReport.$valid) {\n confirmCreateFatigueReport();\n } else {\n bootbox.alert(\"Please fill in all the required fields.\");\n }\n }\n\n function confirmCreateFatigueReport() {\n bootbox.dialog({\n message: \"Would you like to proceed with the Fatigue Report?

\",\n title: \"Send Report\",\n buttons: {\n confirm: {\n label: 'Confirm',\n className: \"btn-success\",\n callback: function callback() {\n $scope.showPanel = \"loading\";\n SafetyReportFactory.saveFatigueReport($scope.formData).then(function (res) {\n return handleSubmitResponse(res);\n });\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n\n function handleSubmitResponse(res) {\n var alertStyle = res.success ? \"success\" : \"warning\";\n bootbox.dialog({\n message: \"
\" + res.message + \"
\",\n title: \"Response Message\",\n buttons: {\n cancel: {\n label: \"Close\",\n className: \"btn-default\",\n callback: function callback() {\n if (res.success) {\n $timeout(gotoFlightInfo(flightId));\n } else {\n $timeout($scope.showPanel = \"submit\");\n }\n }\n }\n }\n });\n }\n\n function sendFatigueReport(formData) {\n $scope.submitted = true;\n\n if ($scope.fatigueReport.$valid && !$scope.isRequiredFieldEmpty(formData.signsPhysical) && !$scope.isRequiredFieldEmpty(formData.signsCognitive) && !$scope.isRequiredFieldEmpty(formData.signsEmotional)) {\n createFatigueReport();\n } else {\n bootbox.alert(\"Please fill in all the required fields.\");\n }\n }\n\n function createFatigueReport() {\n bootbox.dialog({\n message: \"Would you like to send the Fatigue Report?

\",\n title: \"Send Report\",\n buttons: {\n confirm: {\n label: 'Confirm',\n className: \"btn-success\",\n callback: function callback() {\n $scope.showPanel = \"loading\";\n SafetyReportFactory.emailFatigueReport($scope.formData).then(function (res) {\n return handleSubmitResponse(res);\n });\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n\n function isFileTooLarge(image) {\n var isLarge = false;\n\n if (image && image.dataURL != null) {\n isLarge = image.dataURL.length > $scope.sizeLimitKb * 1024;\n }\n\n return isLarge;\n }\n\n function fileUploaded(data) {\n var fileResult = data; //$scope.imageBrowsed;\n\n var uploadedFile = {};\n uploadedFile.fileBlobb = fileResult.dataURL;\n uploadedFile.description = fileResult.fileType || fileResult.file.type;\n uploadedFile.fileName = fileResult.fileName; // var files = $scope.formData.attachedFiles;\n\n if ($scope.formData.attachedFiles.length < 5) {\n // var n = Object.create(attachedFile);\n $scope.formData.attachedFiles.push(uploadedFile);\n } else {\n $scope.showMaxFiles = true;\n }\n }\n\n function removeFile(attachedFile) {\n var files = $scope.formData.attachedFiles;\n var arrayLenght = files.length;\n var itemIndex = -1;\n\n for (var i = 0; i < arrayLenght; i++) {\n if (files[i].fileName == attachedFile.fileName) {\n itemIndex = i;\n break;\n }\n }\n\n if (itemIndex >= 0) {\n files.splice(itemIndex, 1);\n return attachedFile;\n }\n\n if ($scope.showMaxImages) {\n appendPhoto();\n }\n\n $scope.showMaxImages = false;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('SafetyCtrl', SafetyCtrl);\n\n function SafetyCtrl($scope, operationalPhases, $timeout, $routeParams, FlightFactory, $location, SafetyReportFactory) {\n var flightId = $routeParams.flightId;\n var flight = FlightFactory.getFlightFromStorage(flightId);\n $scope.flight = flight;\n $scope.operationalPhases = angular.fromJson(operationalPhases);\n $scope.responseMessage = \"\";\n $scope.showPanel = \"submit\";\n $scope.formData = {\n flightId: $routeParams.flightId,\n flightNo: flight.FlightNo,\n flightDate: flight.ScheduledDeparture,\n flightDep: flight.Departure,\n flightArr: flight.Arrival,\n flightRegistration: flight.AcTailNo,\n occurenceTitle: \"\",\n description: \"\",\n selectedPhase: \"\",\n attachedFiles: [],\n isConfidential: false\n };\n $scope.sizeLimitKb = 25000;\n $scope.fileTooLargeMsg = false;\n $scope.fileUploaded = fileUploaded;\n $scope.removeFile = removeFile;\n $scope.isIFileTooLarge = isFileTooLarge;\n $scope.submitForm = submitForm;\n\n function gotoFlightInfo(flightId) {\n $location.path('/flightinfo/' + flightId);\n }\n\n function submitForm() {\n if ($scope.formCabinReport.$valid) {\n confirmCreateReport(); //console.log($scope.formData.attachedFiles); \n } else {\n bootbox.alert(\"Please fill in all the required fields.\");\n }\n }\n\n function confirmCreateReport() {\n bootbox.dialog({\n message: \"Would you like to proceed with the Safety Report?

\",\n title: \"Send Report\",\n buttons: {\n confirm: {\n label: 'Confirm',\n className: \"btn-success\",\n callback: function callback() {\n $scope.showPanel = \"loading\";\n SafetyReportFactory.saveSafetyReport($scope.formData).then(function (res) {\n return handleSubmitResponse(res);\n });\n }\n },\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n\n function handleSubmitResponse(res) {\n var alertStyle = res.success ? \"success\" : \"warning\";\n bootbox.dialog({\n message: \"
\" + res.message + \"
\",\n title: \"Response Message\",\n buttons: {\n cancel: {\n label: \"Close\",\n className: \"btn-default\",\n callback: function callback() {\n if (res.success) {\n $timeout(gotoFlightInfo(flightId));\n } else {\n $timeout($scope.showPanel = \"submit\");\n }\n }\n }\n }\n });\n }\n\n function isFileTooLarge(image) {\n var isLarge = false;\n\n if (image && image.dataURL != null) {\n isLarge = image.dataURL.length > $scope.sizeLimitKb * 1024;\n }\n\n return isLarge;\n }\n\n function fileUploaded(data) {\n var fileResult = data; //$scope.imageBrowsed;\n\n var uploadedFile = {};\n\n if (isFileTooLarge(data)) {\n $scope.fileTooLargeMsg = true;\n } else {\n $scope.fileTooLargeMsg = false;\n uploadedFile.fileBlobb = fileResult.dataURL;\n uploadedFile.description = fileResult.fileType || fileResult.file.type;\n uploadedFile.fileName = fileResult.fileName; // var files = $scope.formData.attachedFiles;\n\n if ($scope.formData.attachedFiles.length < 5) {\n // var n = Object.create(attachedFile);\n $scope.formData.attachedFiles.push(uploadedFile);\n } else {\n $scope.showMaxFiles = true;\n }\n }\n }\n\n function removeFile(attachedFile) {\n var files = $scope.formData.attachedFiles;\n var arrayLenght = files.length;\n var itemIndex = -1;\n\n for (var i = 0; i < arrayLenght; i++) {\n if (files[i].fileName == attachedFile.fileName) {\n itemIndex = i;\n break;\n }\n }\n\n if (itemIndex >= 0) {\n files.splice(itemIndex, 1);\n return attachedFile;\n }\n\n if ($scope.showMaxImages) {\n appendPhoto();\n }\n\n $scope.showMaxImages = false;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('SafetyReportFactory', SafetyReportFactory);\n\n function SafetyReportFactory($http, apiUrl) {\n var submitResponseObj = {\n success: false,\n message: ''\n };\n var service = {\n saveSafetyReport: saveSafetyReport,\n saveFatigueReport: saveFatigueReport,\n emailFatigueReport: emailFatigueReport\n };\n\n function saveSafetyReport(safetyReport) {\n var aqdBaseURL = apiUrl + '/SafetyReports/SaveSafetyReport';\n return $http.post(aqdBaseURL, safetyReport, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getResponse(res);\n })[\"catch\"](function (res) {\n return getResponseFailed(res);\n });\n }\n\n function saveFatigueReport(fatigueReport) {\n var aqdBaseURL = apiUrl + '/SafetyReports/SaveFatigueReport';\n return $http.post(aqdBaseURL, fatigueReport, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getFatigueResponse(res);\n })[\"catch\"](function (res) {\n return getResponseFailed(res);\n });\n }\n\n function getResponse(res) {\n submitResponseObj.success = res.data.success;\n\n if (res.data.success) {\n submitResponseObj.message = \"Safety Report Submited successfully\";\n } else {\n submitResponseObj.message = res.data.errorMessage;\n }\n\n return submitResponseObj;\n }\n\n function getResponseFailed(res) {\n submitResponseObj.success = false;\n submitResponseObj.message = \"Something went wrong!\";\n return submitResponseObj;\n }\n\n function emailFatigueReport(fatigueReport) {\n var aqdBaseURL = apiUrl + '/SafetyReports/EmailFatigueReport';\n return $http.post(aqdBaseURL, fatigueReport, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return getFatigueResponse(res);\n })[\"catch\"](function (res) {\n return getFatigueResponseFailed(res);\n });\n }\n\n function getFatigueResponse(res) {\n submitResponseObj.success = res.data.success;\n\n if (res.data.success) {\n submitResponseObj.message = \"Fatigue Report sent successfully.\";\n } else {\n submitResponseObj.message = res.data.errorMessage;\n }\n\n return submitResponseObj;\n }\n\n function getFatigueResponseFailed(res) {\n submitResponseObj.success = false;\n submitResponseObj.message = \"Something went wrong!\";\n return submitResponseObj;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('AcknowledgeModalCtrl', AcknowledgeModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name AcknowledgeModalCtrl\r\n * @description \r\n * Warning Modal about unread mandatory memos\r\n * @ngInject\r\n */\n\n function AcknowledgeModalCtrl($scope, ScheduleAcknowledgeFactory, $route, $uibModalInstance) {\n $scope.ConfirmAcknowledge = ConfirmAcknowledge;\n $scope.cancel = cancel;\n $scope.showContent = 'confirm';\n $scope.responseObj = {\n success: false,\n message: '',\n Results: []\n };\n $scope.results = [];\n\n function ConfirmAcknowledge() {\n $scope.showContent = 'loading';\n ScheduleAcknowledgeFactory.acknowledgeChanges().then(function (res) {\n return handleSubmitResponse(res);\n })[\"catch\"](function (res) {\n return handleSubmitResponse(res);\n });\n }\n\n function handleSubmitResponse(res) {\n $scope.showContent = 'results';\n $scope.responseObj = res;\n }\n /**\r\n * Closes modal\r\n * @memberof ProposalInfoModalCtr\r\n */\n\n\n function cancel() {\n $uibModalInstance.close('cancel');\n\n if ($scope.responseObj.success) {\n $route.reload();\n }\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('ScheduleAcknowledgeFactory', ScheduleAcknowledgeFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ScheduleAcknowledgeFactory\r\n * @description \r\n * Get list, Update list & Acknowledge schedule changes\r\n * @ngInject\r\n */\n\n function ScheduleAcknowledgeFactory(localStorageMD5Service, GenericService, $http, apiUrl, defaultCalendarDate) {\n /**\r\n * Initialize the ScheduleChanges\r\n * @memberof ScheduleAcknowledgeFactory\r\n */\n function ScheduleChanges() {\n this.dates = [];\n this.showScheduleChangesModal = false;\n }\n\n var objType = 'ScheduleChanges';\n var objCallback = ScheduleChanges;\n var response = {\n success: false,\n message: '',\n Results: []\n };\n var service = {\n setAllScheduleChangesToStorage: setAllScheduleChangesToStorage,\n getScheduleChangesFromStorage: getScheduleChangesFromStorage,\n updateShowScheduleChangesModal: updateShowScheduleChangesModal,\n showScheduleChangesModal: showScheduleChangesModal,\n hasScheduleChanges: hasScheduleChanges,\n acknowledgeChanges: acknowledgeChanges\n };\n /**\r\n * Save All Schedule changes\r\n * @param {array} objList \r\n */\n\n function setAllScheduleChangesToStorage(objList) {\n if (objList == null || !objList.length > 0) {\n GenericService.removeAll(objType);\n } else {\n var scheduleChanges = {\n dates: objList,\n showScheduleChangesModal: true\n };\n GenericService.saveOne(scheduleChanges, objType, objCallback);\n }\n }\n /**\r\n * Get all Schedule changes\r\n */\n\n\n function getScheduleChangesFromStorage() {\n var dateList = [];\n var scheduleChanges = GenericService.getOne(objType, objCallback);\n\n if (scheduleChanges != null && scheduleChanges.dates != null) {\n scheduleChanges.dates.forEach(function (dateS) {\n var stringToDate = moment.utc(dateS);\n dateList.push(stringToDate);\n });\n }\n\n return dateList;\n }\n /* Update scheduleChanges object to storage\r\n * @memberof ScheduleAcknowledgeFactory\r\n * @param {bool} canShowModal whether the modal can be display\r\n */\n\n\n function updateShowScheduleChangesModal(canShowModal) {\n var scheduleChanges = GenericService.getOne(objType, objCallback);\n scheduleChanges.showScheduleChangesModal = canShowModal;\n GenericService.saveOne(scheduleChanges, objType, objCallback);\n }\n /**\r\n * ShowScheduleChangesModal check\r\n * @memberof ScheduleAcknowledgeFactory\r\n * @returns {bool} returns the value of showScheduleChangesModal property\r\n */\n\n\n function showScheduleChangesModal() {\n var scheduleChanges = GenericService.getOne(objType, objCallback);\n\n if (scheduleChanges && scheduleChanges.dates != null && scheduleChanges.dates.length > 0) {\n var fistChange = moment.utc(scheduleChanges.dates[0]);\n var today = moment.utc();\n\n if (defaultCalendarDate) {\n today = moment.utc(defaultCalendarDate);\n }\n\n var datediff = fistChange.diff(today, 'days');\n return datediff <= 1 && scheduleChanges.showScheduleChangesModal;\n } else {\n return false;\n }\n }\n\n function hasScheduleChanges() {\n var dates = getScheduleChangesFromStorage();\n return dates != null && dates.length > 0;\n }\n /**\r\n * Acknowledge Changes \r\n * @param {date} dateFrom The first schedule change date\r\n * @param {date} dateTo The last schedule change date\r\n * @returns {promise} response\r\n */\n\n\n function acknowledgeChanges() {\n //get dates from local storage\n var datesToAcknowledge = getScheduleChangesFromStorage();\n return $http.post(apiUrl + '/ScheduleAcknowledge/AcknowledgeScheduleChanges', datesToAcknowledge, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return updateScheduleChangesCallBack(res);\n })[\"catch\"](function (res) {\n return acknowledgeFailedCallBack(res);\n });\n }\n /**\r\n * Update Schedule changes dates\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} response\r\n */\n\n\n function updateScheduleChangesCallBack(res) {\n response.success = res.data.success;\n\n if (res.data.success) {\n //update local storage\n setAllScheduleChangesToStorage(res.data.data.DatesWithChanges);\n response.message = \"Success! Your Acknowledge has been sent\";\n response.Results = res.data.data.Results;\n } else {\n response.message = res.data.errorMessage;\n }\n\n return response;\n }\n /**\r\n * The callback function upon failure on submit\r\n * @returns {object} response\r\n */\n\n\n function acknowledgeFailedCallBack(res) {\n response.success = false;\n response.message = \"Oops! Something went wrong\";\n\n if (res.data.data && res.data.data.Results) {\n response.Results = res.data.data.Results;\n }\n\n return response;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('SearchFlightsCtrl', SearchFlightsCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SearchFlightsCtrl\r\n * @description \r\n * Search Flight info modal\r\n * @ngInject\r\n */\n\n function SearchFlightsCtrl($scope, $uibModalInstance, $route, $location, defaultCalendarDate, SearchFlightsFactory, GroundDutyFactory, FlightFactory) {\n $scope.showContent = 'search';\n $scope.hasError = false;\n $scope.flightFound = null;\n $scope.searchFlights = searchFlights;\n $scope.searchCriteriaContent = searchCriteriaContent;\n $scope.closeModal = closeModal;\n $scope.gotoSelectedFlightInfo = gotoSelectedFlightInfo;\n $scope.validationFormError = '';\n $scope.hasPublishedRoster = true; //Date picker:\n\n $scope.openDatepicker = openDatepicker;\n var today = new Date().toUTC();\n\n if (defaultCalendarDate) {\n today = new Date(defaultCalendarDate).toUTC();\n }\n\n function openDatepicker() {\n $scope.searchCriteria.flightDatePicker.opened = true;\n }\n\n updateSearchCriteriaScope();\n\n function updateSearchCriteriaScope() {\n var fromDate = null;\n var toDate = null;\n var groundDutyDates = GroundDutyFactory.getFirstAndLastDateOfGroundDuties();\n var flightDates = FlightFactory.getTheFirstAndTheLastFlightDates();\n\n if (groundDutyDates && flightDates && groundDutyDates.firstDate && flightDates.firstDate) {\n fromDate = groundDutyDates.firstDate < flightDates.firstDate ? groundDutyDates.firstDate : flightDates.firstDate;\n toDate = groundDutyDates.lastDate > flightDates.lastDate ? groundDutyDates.lastDate : flightDates.lastDate;\n } else {\n $scope.hasPublishedRoster = false;\n $scope.showContent = \"results\";\n $scope.hasError = true;\n }\n\n $scope.searchCriteria = {\n flightDatePicker: {\n value: today,\n format: 'dd-MM-yyyy',\n opened: false,\n options: {\n minDate: fromDate,\n maxDate: toDate\n }\n },\n flightNo: \"\",\n departure: \"\",\n arrival: \"\"\n };\n }\n\n function searchFlights() {\n $scope.hasError = false;\n\n if ($scope.searchCriteria.flightNo.length == 0 && $scope.searchCriteria.departure.length == 0 && $scope.searchCriteria.arrival.length == 0) {\n $scope.validationFormError = 'Ensure that at least one optional value is provided.';\n } else {\n $scope.showContent = 'loading';\n SearchFlightsFactory.getFlights($scope.searchCriteria).then(function (res) {\n return handleResponse(res);\n })[\"catch\"](function (res) {\n return handleFailedResponse(res);\n });\n }\n }\n\n function handleResponse(res) {\n $scope.showContent = 'results';\n\n if (res.data && res.data.success && res.data.data) {\n $scope.flightsFound = res.data.data; //auto redirect when only one flight in results:\n // if($scope.flightsFound.lenght == 1){\n // gotoSelectedFlightInfo($scope.flightsFound[0].flightId, $scope.flightsFound[0].flightDate, $scope.flightsFound[0].flightNo, $scope.flightsFound[0].departure);\n // }\n } else {\n $scope.hasError = true;\n }\n }\n\n function handleFailedResponse(res) {\n $scope.showContent = 'results';\n $scope.hasError = true;\n }\n\n function searchCriteriaContent() {\n $scope.showContent = 'search';\n }\n /**\r\n * Redirect to selected flight info\r\n */\n\n\n function gotoSelectedFlightInfo(flightId, flightDate, flightNo, departure) {\n closeModal();\n $location.path('/selectedflightinfo/' + flightId + '/' + flightDate + '/' + flightNo + '/' + departure);\n }\n /**\r\n * Close the modal\r\n * @memberof SearchPastGDCtrl\r\n */\n\n\n function closeModal() {\n $uibModalInstance.close('cancel');\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('SearchFlightsFactory', SearchFlightsFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SearchFlightsFactory\r\n * @description \r\n * Get selected flight info\r\n * @ngInject\r\n */\n\n function SearchFlightsFactory($http, $q, apiUrl, $timeout) {\n var service = {\n getFlights: getFlights,\n getFlightInfo: getFlightInfo\n };\n\n function getFlights(criteria, callback) {\n //test UI:\n //return getFlightsDummy(criteria)\n var flightDate = criteria.flightDatePicker.value.toString('yyyy-MM-dd');\n var uri = encodeURI(apiUrl + '/SearchFlights/GetFlights?flightDate=' + flightDate + '&flightNo=' + criteria.flightNo + '&departure=' + criteria.departure + '&arrival=' + criteria.arrival);\n return $http.get(uri, {\n 'Content-Type': 'application/json'\n })[\"catch\"](callback);\n }\n\n function getFlightInfo(flightId, flightDate, flightNo, departure, callback) {\n var flightDateStr = flightDate.toString('yyyy-MM-dd'); // $http({\n // url: apiUrl + '/SearchFlights/GetFlightInfo', \n // method: \"GET\",\n // contentType: \"application/json\",\n // params: {flightId: flightId, flightDate: flightDateStr, flightNo: flightNo, departure: departure}\n // });\n\n var uri = encodeURI(apiUrl + '/SearchFlights/GetFlightInfo?flightId=' + flightId + '&flightDate=' + flightDateStr + '&flightNo=' + flightNo + '&departure=' + departure);\n return $http.get(uri, {\n 'Content-Type': 'application/json'\n })[\"catch\"](callback);\n }\n\n function getFlightsDummy(criteria) {\n // Create a deferred object to handle the promise\n var deferred = $q.defer(); // Simulate an asynchronous operation (e.g., API call) with a delay\n\n $timeout(function () {\n var flightDate = criteria.flightDatePicker.value.toString('yyyy-MM-dd'); // Simulate getting flight data asynchronously\n\n var testSuccessResults = {\n data: getDummyFlightResults(),\n success: true,\n errorMessage: \"\"\n }; // Resolve the promise with the retrieved data\n\n deferred.resolve(testSuccessResults);\n }, 2000); // Return the promise\n\n return deferred.promise;\n }\n\n function getDummyFlightResults() {\n return {\n \"FlightsFound\": [{\n \"Id\": 1,\n \"FlightNo\": \"A3123\",\n \"FlightDate\": \"2023-10-20T00:00:00\",\n \"Registration\": \"AAA-OK1\",\n \"STD\": \"2023-10-20T08:00:00\",\n \"STA\": \"2023-10-20T12:00:00\",\n \"Departure\": \"ATH\",\n \"Arrival\": \"SKG\"\n }, {\n \"Id\": 2,\n \"FlightNo\": \"A3789\",\n \"FlightDate\": \"2023-10-21T00:00:00\",\n \"Registration\": \"AAA-OK2\",\n \"STD\": \"2023-10-21T15:30:00\",\n \"STA\": \"2023-10-21T19:30:00\",\n \"Departure\": \"SKG\",\n \"Arrival\": \"ATH\"\n }, {\n \"Id\": 3,\n \"FlightNo\": \"OA456\",\n \"FlightDate\": \"2023-10-22T00:00:00\",\n \"Registration\": \"CCC-OK3\",\n \"STD\": \"2023-10-22T10:15:00\",\n \"STA\": \"2023-10-22T14:15:00\",\n \"Departure\": \"ATH\",\n \"Arrival\": \"SKG\"\n }]\n };\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('SelectedFlightCtrl', SelectedFlightCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SelectedFlightCtrl\r\n * @description \r\n * Show selected Flight info page\r\n * @ngInject\r\n */\n\n function SelectedFlightCtrl($scope, $routeParams, defaultCalendarDate, SearchFlightsFactory, $timeout, waterUpliftSupportingAcTypes) {\n //get value from routeParams:\n var flightId = $routeParams.flightId;\n var flightDate = $routeParams.flightDate;\n var flightNo = $routeParams.flightNo;\n var departure = $routeParams.departure;\n window.addEventListener('online', function (e) {\n $timeout(checkConnectionStatus());\n });\n $scope.init = checkConnectionStatus();\n $scope.contentToShow = \"loading\";\n $scope.flightInfo = null;\n $scope.hasFlightInfo = false;\n $scope.pilotCrewMembers = [];\n $scope.cabinCrewMembers = [];\n $scope.dhcCrewMembers = [];\n $scope.waterQuantity = null;\n $scope.supportsWaterUpliftAcType = false;\n $scope.crewRouteInfoPanel = {\n hasAircraftPositions: true,\n crewRouteDuties: []\n };\n /**\r\n * Checks if the client is online or offline \r\n * @memberof SelectedFlightCtrl \r\n */\n\n function checkConnectionStatus() {\n var isOnline = window.navigator.onLine;\n\n if (isOnline) {\n getFlightInfo();\n } else {\n showError(\"Please check your internet connection!\");\n }\n }\n\n function getFlightInfo() {\n SearchFlightsFactory.getFlightInfo(flightId, flightDate, flightNo, departure).then(function (res) {\n return handleResponse(res);\n })[\"catch\"](function (res) {\n return handleFailedResponse(res);\n });\n }\n\n function handleResponse(res) {\n if (res.data.success) {\n if (res.data.data && res.data.data.Flight) {\n $scope.flightInfo = res.data.data;\n updateFlightInfoScopes(res.data.data);\n updateCrewMembersScopes();\n updatePaxPanelScopes();\n $scope.contentToShow = 'results';\n $scope.hasFlightInfo = true;\n } else {\n showError(\"Flight Info not found.\");\n }\n } else {\n showError(res.data.errorMessage);\n }\n }\n\n function handleFailedResponse(res) {\n $scope.contentToShow = 'results';\n $scope.hasError = true;\n showError(res.errorMessage);\n }\n /**\r\n * Displays the error message\r\n * @memberof SelectedFlightCtrl \r\n * @param {string} message message to display\r\n */\n\n\n function showError(message) {\n $scope.contentToShow = \"error\";\n $scope.errorMessage = message;\n }\n\n function updateCrewMembersScopes() {\n $scope.pilotCrewMembers = $scope.flightInfo.CrewInfo.filter(function (x) {\n return (x.PositionCode == 'CP' || x.PositionCode == \"FO\") && !x.DHC;\n });\n $scope.cabinCrewMembers = $scope.flightInfo.CrewInfo.filter(function (x) {\n return (x.PositionCode == 'SA' || x.PositionCode == \"FA\") && !x.DHC;\n });\n $scope.dhcCrewMembers = $scope.flightInfo.CrewInfo.filter(function (x) {\n return x.DHC;\n });\n }\n\n function updatePaxPanelScopes() {\n $scope.supportsWaterUpliftAcType = waterUpliftSupportingAcTypes.includes($scope.flightInfo.AcType);\n getWaterQuantity();\n }\n\n function getWaterQuantity() {\n var totalPax = $scope.flightInfo.Flight.BOOKED_C + $scope.flightInfo.Flight.BOOKED_Y;\n var startDate = moment($scope.flightInfo.Flight.STD);\n var endDate = moment($scope.flightInfo.Flight.STA);\n var duration = moment.duration(endDate.diff(startDate)).asHours();\n var waterQuantity = (0, 18 * totalPax * duration) / 200;\n var formattedwaterQuantity = waterQuantity.toString().substring(0, 4);\n $scope.waterQuantity = formattedwaterQuantity;\n\n if (waterQuantity) {\n $scope.supportsWaterUpliftAcType = true;\n }\n }\n\n function updateFlightInfoScopes(flightInfoObj) {\n var flight = {};\n flight.showPreviousAcPos = true;\n flight.showNextAcPos = true;\n flight.hasChangeAircraft = false;\n flight.DutyType = 'Flight';\n flight.FlightId = flightInfoObj.Flight.FlightId;\n flight.FlightNo = flightInfoObj.Flight.FlightNo;\n flight.Departure = flightInfoObj.Flight.DEP;\n flight.Arrival = flightInfoObj.Flight.ARR;\n flight.AcTailNo = flightInfoObj.Flight.Registration;\n flight.AcType = flightInfoObj.Flight.AcType;\n flight.DepartureStand = flightInfoObj.Flight.DEPSTAND;\n flight.ArrivalStand = flightInfoObj.Flight.ARRSTAND;\n flight.BookedC = flightInfoObj.Flight.BOOKED_C;\n flight.BookedY = flightInfoObj.Flight.BOOKED_Y;\n flight.ScheduledDeparture = flightInfoObj.Flight.STD;\n var STD = new Date(flight.ScheduledDeparture);\n flight.ScheduledDepartureDateUTC = STD.toString('yyyy-MM-dd');\n flight.ScheduledDepartureTimeUTC = STD.toString('HH:mm');\n flight.ScheduledArrival = flightInfoObj.Flight.STA;\n flight.CTOT = flightInfoObj.Flight.CTOT;\n flight.ETD = flightInfoObj.Flight.ETD;\n flight.ATD = flightInfoObj.Flight.ATD;\n flight.ETA = flightInfoObj.Flight.ETA;\n flight.ATA = flightInfoObj.Flight.ATA;\n flight.DepartureCountryISO = flightInfoObj.Flight.DepartureCountryISO;\n flight.ArrivalCountryISO = flightInfoObj.Flight.ArrivalCountryISO;\n flight.DepartureEU = flightInfoObj.Flight.DepartureEU;\n flight.ArrivalEU = flightInfoObj.Flight.ArrivalEU;\n flight.DepartureSchengen = flightInfoObj.Flight.DepartureSchengen;\n flight.ArrivalSchengen = flightInfoObj.Flight.ArrivalSchengen;\n var diffMin = Date.DifferenceInMinutes(flight.ScheduledDeparture, flight.ScheduledArrival);\n flight.BTime = Date.MinutesToStringSimple(diffMin);\n flight.Delay = moment(flight.ATD).diff(moment(flight.ScheduledDeparture), 'minutes') || \"\";\n flight.ArrDelay = moment(flight.ATA).diff(moment(flight.ScheduledArrival), 'minutes') || \"\";\n flight.flightDelays = {};\n flight.flightDelays.TotalDelay = flightInfoObj.FlightDelays.TotalDelay;\n flight.flightDelays.UnJustified = flightInfoObj.FlightDelays.UnJustified;\n flight.flightDelays.DC93 = flightInfoObj.FlightDelays.DC93;\n flight.flightDelays.DC9 = flightInfoObj.FlightDelays.DC9; //flight.crewMeals : no info\n\n flight.aircaftPositions = flightInfoObj.AircaftPositions;\n $scope.crewRouteInfoPanel.crewRouteDuties.push(flight);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.service(\"SWUpdateService\", SWUpdateService);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc service\r\n * @name SWUpdateService\r\n * @description \r\n * manages the service-worker update\r\n * @ngInject\r\n */\n\n function SWUpdateService(LogService) {\n /**\r\n * initialize service worker\r\n * @memberof SWUpdateService\r\n */\n function initialize() {\n // Delay registration until after the page has loaded\n window.addEventListener('load', function () {\n //kill switch. uncomment this and comment out everything else sw related\n // navigator.serviceWorker.getRegistrations().then(function (registrations) {\n // //returns installed service workers\n // if (registrations.length) {\n // for(var registration of registrations) {\n // registration.unregister();\n // }\n // }\n // });\n //register the service worker and work with the promise it returns\n navigator.serviceWorker.register('service-worker.js').then(function (reg) {\n // use a variable to make sure we refresh the page only once\n var refreshing; //fires when a new Service Worker takes control of the current page (refreshes the page)\n\n navigator.serviceWorker.addEventListener('controllerchange', function () {\n if (refreshing) return;\n refreshing = true;\n window.location.reload();\n });\n })[\"catch\"](function (e) {\n LogService.error(e, 'Tried to register the service worker');\n });\n });\n }\n /**\r\n * poll the server for new service worker file (new app version)\r\n * @memberof SWUpdateService\r\n */\n\n\n function checkUpdates(reg) {\n if (reg == null) return; //ask server for new service worker\n\n reg.update();\n }\n /**\r\n * If new service worker has been waiting too long, force update\r\n * @memberof SWUpdateService\r\n */\n\n\n function checkVersionExpiration(reg) {\n if (reg == null) return;\n reg.waiting.postMessage('checkVersionExpiration');\n }\n /**\r\n * Activate the new service worker that was waiting\r\n * @memberof SWUpdateService\r\n */\n\n\n function update(reg) {\n reg.waiting.postMessage('skipWaiting');\n }\n\n return {\n initialize: initialize,\n checkUpdates: checkUpdates,\n checkVersionExpiration: checkVersionExpiration,\n update: update\n };\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('traineeSyllabus', traineeSyllabus);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name traineeSyllabus\r\n * @restrict E\r\n * @description\r\n * Initialize read only view of submitted syllabus\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function traineeSyllabus() {\n function link(scope) {\n setSyllabus(scope.traineeSession);\n\n function setSyllabus(traineeSession) {\n var traineeSessionItems = [];\n scope.phase.Syllabus.ActiveVersion.SyllabusItems.forEach(function (item) {\n if (item.Active == true) {\n var syllabusItem = JSON.parse(JSON.stringify(item));\n syllabusItem.Tries = [];\n syllabusItem.Selected = false;\n var relatedSessionItem = null;\n\n if (scope.type == \"signature\") {\n relatedSessionItem = traineeSession.Items.find(function (x) {\n return x.Id == syllabusItem.Id;\n });\n } else {\n relatedSessionItem = traineeSession.Items.find(function (x) {\n return x.SyllabusItemId == syllabusItem.Id;\n });\n }\n\n if (relatedSessionItem) {\n syllabusItem.Selected = true;\n syllabusItem.Tries = relatedSessionItem.Tries;\n syllabusItem.hasRemarks = relatedSessionItem.Tries.some(function (x) {\n return x.Comments && x.Comments.length > 0;\n }) || relatedSessionItem.Tries.some(function (t) {\n return t.TryGrading.Competences.some(function (x) {\n return x.Comments && x.Comments.length > 0;\n });\n });\n syllabusItem.Tries.forEach(function (attempt) {\n attempt.Selected = true;\n });\n }\n\n if (scope.type == \"signature\") {\n setPanelStyleByProgress(syllabusItem);\n } else {\n setPanelStyleBySelected(syllabusItem);\n }\n\n traineeSessionItems.push(syllabusItem);\n }\n });\n scope.traineeSession.ItemsGrouped = [];\n scope.traineeSession.ItemsGrouped = SyllabusGrouping(traineeSessionItems);\n }\n\n function setPanelStyleByProgress(item) {\n var historyTriesCount = item.Tries.length;\n var newTriesCount = item.Tries.filter(function (x) {\n return !x.isReadOnly && x.Selected;\n }).length;\n item.TriesPerformedCount = historyTriesCount + newTriesCount;\n var completedItem = item.TriesPerformedCount >= item.MandatoryCount;\n\n if (item.MandatoryCount == 0) {\n //non-mandatory items are considered completed if performed at least once\n completedItem = item.TriesPerformedCount >= 1;\n }\n\n if (completedItem) {\n item.PanelClass = 'panel-green panel-border-left-green ';\n } else {\n item.PanelClass = 'panel-border-left-blue ';\n }\n }\n\n function setPanelStyleBySelected(item) {\n var historyTriesCount = item.Tries.length;\n item.TriesPerformedCount = historyTriesCount;\n var completedItem = item.TriesPerformedCount >= item.Mandatory;\n\n if (completedItem) {\n item.PanelClass = 'panel-green panel-border-left-green ';\n } else {\n item.PanelClass = 'panel-border-left-blue ';\n }\n }\n\n function SyllabusGrouping(items) {\n //Syllabus Items Group By 'GroupId'\n var syllabusGroups = [];\n items.forEach(function (item) {\n if (!syllabusGroups.some(function (x) {\n return x.Id == item.SelectedGroup.Id;\n })) {\n if (!item.SelectedGroup) {\n item.SelectedGroup = {\n Id: 0,\n Title: 'General'\n };\n }\n\n var syllabusGroup = {\n Id: item.SelectedGroup.Id,\n Title: item.SelectedGroup.Title ? item.SelectedGroup.Title : 'General',\n Items: []\n };\n syllabusGroup.Items.push(item);\n syllabusGroups.push(syllabusGroup);\n } else {\n syllabusGroups.filter(function (x) {\n return x.Id == item.SelectedGroup.Id;\n })[0].Items.push(item);\n }\n });\n return syllabusGroups;\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: 'views/TraineeCourse/trainee-syllabus.tpl.html',\n scope: {\n phase: \"=\",\n traineeSession: \"=\",\n type: \"=\"\n },\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('TraineeCourseCtrl', TraineeCourseCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name TraineeCourseCtrl\r\n * @description \r\n *\r\n * @ngInject\r\n */\n\n function TraineeCourseCtrl($scope, $routeParams, TraineeCoursesDetailsFactory, TrainingSessionFactory, $location) {\n var traineeCourseId = Number($routeParams.traineeCourseId);\n $scope.hasError = false;\n $scope.isLoading = true;\n $scope.courseDate = $routeParams.date;\n $scope.isTraineeView = true;\n $scope.gotoCalendar = gotoCalendar;\n $scope.setSelectedPhase = setSelectedPhase;\n $scope.responseObj = {\n success: false,\n message: '',\n Results: []\n };\n $scope.results = [];\n $scope.showWarning = false;\n TraineeCoursesDetailsFactory.getTraineeCourse(traineeCourseId).then(function (res) {\n return handleSubmitResponse(res);\n })[\"catch\"](function (res) {\n return handleFailedResponse(res);\n });\n\n function handleSubmitResponse(res) {\n $scope.responseObj = res;\n\n if (res.success) {\n $scope.traineeCourse = res.Results.data.traineeCourse;\n $scope.courseDetails = res.Results.data.courseDetails;\n $scope.traineeCourse.Phases.forEach(function (phase) {\n phase.StatusClass = '';\n\n if (phase.PhaseStatus == 'InProgress') {\n phase.StatusClass = \"border-left-blue\";\n phase.TextClass = \"text-blue\";\n phase.BtnClass = \"bg-blue text-white\";\n } else if (phase.PhaseStatus == 'Pending') {\n phase.StatusClass = \"border-left-gray \";\n phase.TextClass = \"text-gray\";\n phase.BtnClass = \"bg-gray text-white\";\n } else if (phase.PhaseStatus == 'Completed') {\n phase.StatusClass = \"border-left-green\";\n phase.TextClass = \"text-green\";\n phase.BtnClass = \"bg-green text-white\";\n }\n });\n $scope.traineeCourse.Phases.forEach(function (phase) {\n phase.Sessions.forEach(function (sessionTrainee) {\n if (sessionTrainee) {\n $scope.traineeSession = sessionTrainee;\n $scope.traineeSession.hasDayGrading = sessionTrainee.DayGrading.Comments || sessionTrainee.DayGrading.GradeType != 'NotSet' && sessionTrainee.DayGrading.Grade || sessionTrainee.DayGrading.Competences.length > 0;\n $scope.traineeSession.hasReleaseGrading = sessionTrainee.ReleaseGrading.Comments || sessionTrainee.ReleaseGrading.GradeType != 'NotSet' && sessionTrainee.ReleaseGrading.Grade || sessionTrainee.ReleaseGrading.Competences.length > 0;\n $scope.traineeSession.AcTypes = [];\n $scope.traineeSession.AcTypes = _toConsumableArray(new Set($scope.traineeSession.Sectors.map(function (ses) {\n return ses.AcType;\n }))); //GroupBy AcType\n\n $scope.traineeSession.SectorsByAcType = [];\n $scope.traineeSession.AcTypes.forEach(function (acType) {\n var group = {\n AcType: acType,\n Sectors: $scope.traineeSession.Sectors.filter(function (x) {\n return x.AcType == acType;\n })\n };\n $scope.traineeSession.SectorsByAcType.push(group);\n });\n } else {\n trainee.Session = {\n Released: course.selectedPhase.ModuleType == \"Training\" ? false : true,\n CrewId: trainee.CrewId,\n Items: [],\n Absent: false,\n DayGrading: {\n Comments: null,\n Grade: null,\n Competences: []\n },\n ReleaseGrading: {\n Comments: null,\n Grade: null,\n Competences: []\n },\n NeedsAdditionalTraining: false,\n AdditionalTrainingRemarks: null,\n CompleteAdditionalTraining: false\n };\n }\n });\n getSelectedPhase($scope.traineeCourse);\n var phaseId = $scope.traineeCourse.Phases[0].PhaseId;\n initPhaseDetails(phaseId);\n });\n } else {\n $scope.showWarning = true;\n $scope.responseObj;\n }\n }\n\n function initPhaseDetails(phaseId) {\n $scope.selectedPhase = $scope.courseDetails.CoursePhases.find(function (x) {\n return x.Id == phaseId;\n });\n $scope.traineePhase = $scope.traineeCourse.Phases.find(function (x) {\n return x.PhaseId == phaseId;\n });\n $scope.selectedTraineePhase = $scope.courseDetails.CoursePhases.find(function (x) {\n return x.Id == phaseId;\n });\n $scope.traineeInstructions = $scope.selectedPhase.TraineeInstructions;\n $scope.examinerInstructions = $scope.selectedPhase.ExaminerInstructions;\n $scope.flatSullabusItems = [];\n $scope.traineeCourse.Phases.forEach(function (phase) {\n phase.Sessions.forEach(function (session) {\n session.Items.forEach(function (item) {\n var flatItem = TrainingSessionFactory.createFlatHistorySullabusItem($scope.traineeCourse, phase, session, item);\n $scope.flatSullabusItems.push(flatItem);\n });\n });\n });\n $scope.flatCourseSullabusItems = [];\n $scope.courseDetails.CoursePhases.filter(function (x) {\n return x.Syllabus;\n }).forEach(function (phase, index, array) {\n phase.Syllabus.ActiveVersion.SyllabusItems.forEach(function (syllabusItem) {\n var syllabusItemHistory = $scope.flatSullabusItems.filter(function (item) {\n return item.ItemId == syllabusItem.Id;\n });\n $scope.flatCourseSullabusItems.push(syllabusItemHistory);\n });\n });\n $scope.isLoading = false;\n }\n\n function handleFailedResponse(res) {\n $scope.hasError = true;\n }\n\n function getSelectedPhase(course) {\n var hasSelectedPhase = false;\n var phases = course.Phases;\n phases.forEach(function (phase, index, array) {\n phase.isFirst = index == 0;\n phase.isLast = index + 1 == array.length; // Select the first InProgress & selected phase\n\n if (!hasSelectedPhase && phase.Status == \"InProgress\" && phase.isSelected) {\n phase.Selected = true;\n hasSelectedPhase = true;\n }\n }); // Select the first InProgress phase\n\n if (!hasSelectedPhase && phases.some(function (x) {\n return x.Status == \"InProgress\";\n })) {\n phases.find(function (x) {\n return x.Status == \"InProgress\";\n }).Selected = true;\n hasSelectedPhase = true;\n }\n\n if (!hasSelectedPhase) {\n phases.find(function (x) {\n return x.isFirst;\n }).Selected = true;\n }\n\n $scope.selectedPhase = phases.find(function (x) {\n return x.Selected;\n });\n return $scope.selectedPhase;\n }\n\n function setSelectedPhase(phaseId) {\n $scope.selectedPhase = $scope.courseDetails.CoursePhases.find(function (x) {\n return x.Id == phaseId;\n });\n $scope.courseDetails.CoursePhases.find(function (x) {\n return x.Id == phaseId;\n }).Selected = true;\n initPhaseDetails(phaseId);\n return $scope.selectedPhase;\n }\n\n function gotoCalendar() {\n $location.path(\"/\");\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('traineeCoursesDetails', traineeCoursesDetails);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name traineeCoursesDetails\r\n * @restrict E\r\n * @description\r\n * Implementation of trainee Courses Details\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function traineeCoursesDetails(TraineeCoursesDetailsFactory, $location, $uibModal, $routeParams) {\n function link(scope, attrs) {\n // scope.getTraineeCourse = getTraineeCourse;\n scope.goToTraineeCourse = goToTraineeCourse;\n scope.goToTraineeFlightCourse = goToTraineeFlightCourse;\n scope.HasTraineeView = true;\n scope.isLoading = false;\n scope.traineeCourses = [];\n scope.traineeFlightCourses = [];\n var dutyId = scope.groundDutyId;\n\n if (dutyId != null) {\n scope.traineeCourses = TraineeCoursesDetailsFactory.getTraineeGroundCourses(dutyId);\n }\n\n if (scope.flightId != null || scope.Flight != null) {\n var flightId = scope.flightId != null ? scope.flightId : scope.Flight.FlightId;\n }\n\n if (flightId != null) {\n scope.traineeFlightCourses = TraineeCoursesDetailsFactory.getTraineeFlightCourses(flightId);\n }\n\n if (scope.traineeCourses.length > 0) {\n var date = scope.groundDuty.DutyDateS;\n }\n\n if (scope.traineeFlightCourses.length > 0) {\n var flightDate = new moment(scope.flight.FlightDate).format(\"DD-MM-YYYY\");\n }\n\n manageCourseStatus(scope.traineeCourses, scope.traineeFlightCourses);\n\n function manageCourseStatus(traineeCourses, traineeFlightCourses) {\n traineeCourses.forEach(function (course) {\n //Pending\n if (course.Status == \"1\") {\n course.StatusClass = \"text-blue\";\n } //Completed\n else if (course.Status == \"2\") {\n course.StatusClass = \"text-green\";\n } //NotCompleted - stopped\n else if (course.Status == \"5\") {\n course.StatusClass = \"text-orange\";\n }\n });\n traineeFlightCourses.forEach(function (course) {\n //Pending\n if (course.Status == \"1\") {\n course.StatusClass = \"text-blue\";\n } //Completed\n else if (course.Status == \"2\") {\n course.StatusClass = \"text-green\";\n } //NotCompleted - stopped\n else if (course.Status == \"5\") {\n course.StatusClass = \"text-orange\";\n }\n });\n }\n /**\r\n * Redirect to Course Session\r\n */\n\n\n function goToTraineeCourse(traineeCourseId) {\n $location.path('/traineecourse/' + traineeCourseId + '/' + dutyId + '/' + date);\n }\n\n function goToTraineeFlightCourse(traineeCourseId) {\n $location.path('/traineecourse/' + traineeCourseId + '/' + flightId + '/' + flightDate);\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/TraineeCourse/trainee-courses-details.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('TraineeCoursesDetailsFactory', TraineeCoursesDetailsFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name TraineeCoursesDetailsFactory\r\n * @description \r\n * Get, Set and Submit Trainee Courses Details.\r\n * @ngInject\r\n */\n\n function TraineeCoursesDetailsFactory(localStorageMD5Service, $http, apiUrl, GenericService, $timeout) {\n var objTypeGround = 'traineeCourses';\n var objTypeFlight = 'traineeFlightCourses';\n var objCallbackGround = TraineeCourses;\n var objCallbackFlights = TraineeFlightCourses;\n window.addEventListener('online', function (e) {\n $timeout(checkConnectionStatus());\n });\n var response = {\n success: false,\n message: '',\n Results: []\n };\n var service = {\n setTraineeCoursesToStorage: setTraineeCoursesToStorage,\n getTraineeGroundCourses: getTraineeGroundCourses,\n getTraineeCourses: getTraineeCourses,\n getTraineeCourse: getTraineeCourse,\n setTraineeFlightCoursesToStorage: setTraineeFlightCoursesToStorage,\n getTraineeFlightCourses: getTraineeFlightCourses,\n getFlightCourses: getFlightCourses\n };\n\n function TraineeCourses() {\n this.DutyDate = null;\n this.Status = null;\n this.GroundDutyId = null;\n }\n\n function checkConnectionStatus() {\n response.success = false;\n response.message = \"Please check the internet connection!\";\n }\n /**\r\n * Set all the trainee courses\r\n * @memberof TraineeCoursesDetailsFactory\r\n * @param {array} objects A list of trainee courses.\r\n */\n\n\n function setTraineeCoursesToStorage(data) {\n GenericService.saveAll(data, objTypeGround, objCallbackGround);\n }\n\n function getTraineeGroundCourses(dutyId) {\n var results = [];\n var listOfValues = localStorageMD5Service.get(objTypeGround);\n\n if (listOfValues) {\n var traineeCoursesPerDuty = listOfValues.filter(function (item) {\n return item.GroundDutyId == dutyId;\n });\n results = traineeCoursesPerDuty.map(function (item) {\n return item;\n });\n }\n\n return results;\n }\n\n function getTraineeCourses() {\n return GenericService.list(objTypeGround, objCallbackGround);\n }\n\n function getFlightCourses() {\n return GenericService.list(objTypeFlight, objCallbackFlights);\n }\n\n function TraineeFlightCourses() {}\n\n function getTraineeCourse(traineeCourseId, callback) {\n return $http.get(apiUrl + '/Training/GetTraineeCourse?traineeCourseId=' + traineeCourseId, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return updateTraineeCourseCallBack(res);\n })[\"catch\"](function (res) {\n return traineeCourseFailedCallBack(res);\n });\n }\n\n function updateTraineeCourseCallBack(res) {\n response.success = res.data.success;\n\n if (res.data.success) {\n response.Results = res.data;\n } else {\n response.message = res.data.errorMessage;\n }\n\n return response;\n }\n /**\r\n * The callback function upon failure on submit\r\n * @returns {object} response\r\n */\n\n\n function traineeCourseFailedCallBack(res) {\n if (!window.navigator.onLine) {\n checkConnectionStatus();\n } else {\n response.success = false;\n response.message = \"Oops! Something went wrong\"; //TODO::Check status=500 error: returns res = {data: {…}, status: 500, config: {…}, statusText: \"Internal Server Error\", headers: ƒ}\n // res.data.data is null\n\n if (res.data.data && res.data.data.Results) {\n response.Results = res.data.data.Results;\n } else {\n //log results\n console.log(res);\n }\n }\n\n return response;\n }\n\n function setTraineeFlightCoursesToStorage(data) {\n GenericService.saveAll(data, objTypeFlight, objCallbackFlights);\n }\n\n function getTraineeFlightCourses(flightId) {\n var results = [];\n var listOfValues = localStorageMD5Service.get(objTypeFlight);\n\n if (listOfValues) {\n var traineeCoursesPerDuty = listOfValues.filter(function (item) {\n return item.FlightId == flightId;\n });\n results = traineeCoursesPerDuty.map(function (item) {\n return item;\n });\n }\n\n return results;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.service(\"InfoAPIService\", InfoAPIService);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc service\r\n * @name InfoAPIService\r\n * @description \r\n * Information service which gets latest pax and gate data\r\n * @ngInject\r\n */\n\n function InfoAPIService($http, $q, apiUrl, LogService, UserFactory, SyncAPIService, FlightFactory, PaxInfoFactory, AircaftPositionsFactory, GroundDutyFactory, CampaignFactory, LuggageComplianceFactory, FlightCheckInsFactory, PhiloxeniaQuestionsFactory, FlightDelaysFactory, CustomerEventHistoryFactory) {\n return {\n getPax: getPax,\n sendCustomerIncident: sendCustomerIncident,\n refreshCrewRoute: refreshCrewRoute,\n updateCrewRouteStatusSetter: updateCrewRouteStatusSetter,\n updateFlightStatusSetter: updateFlightStatusSetter,\n updateGroundStatusSetter: updateGroundStatusSetter,\n updateStatusSetter: updateStatusSetter,\n updateFlightLocalStorage: updateFlightLocalStorage,\n updateGroundDutyLocalStorage: updateGroundDutyLocalStorage,\n updateCrewCheckIn: updateCrewCheckIn,\n updatePhiloxeniaQuestions: updatePhiloxeniaQuestions\n };\n /**\r\n * get latest Passenger information\r\n * @memberof InfoAPIService\r\n * @return {object} promise\r\n */\n\n function getPax(flightId) {\n //Prepare to request training courses fetch\n var flight = FlightFactory.getFlightFromTotalFlights(flightId);\n var flightInfo = {\n FlightId: flightId,\n FlightCourses: flight ? flight.Courses : []\n };\n var user = UserFactory.getUser();\n var call = $q.defer();\n $http.post(apiUrl + '/info/Pax', flightInfo, {\n 'Content-Type': 'application/json'\n }).then(function (responseData) {\n if (responseData == undefined || responseData.data == undefined || responseData.data.data == undefined) {\n var err = new Error();\n err.status = -1;\n var msg = \"ResponseData error in info/gates :\" + JSON.stringify(responseData);\n LogService.debug(msg, err);\n call.reject(err);\n return;\n }\n\n var newDutyInfo = responseData.data.data;\n newDutyInfo.FlightId = flightId;\n updateFlightLocalStorage(newDutyInfo);\n LuggageComplianceFactory.updateLuggageComplianceStorage(newDutyInfo.LuggageCompliance, flightId);\n updateCrewCheckIn(newDutyInfo);\n updatePhiloxeniaQuestions(newDutyInfo);\n FlightDelaysFactory.upsertFlightDelays(newDutyInfo.FlightDelays);\n call.resolve(responseData);\n }, function (err) {\n call.reject(err);\n });\n return call.promise;\n }\n /**\r\n * Send Customer Incident\r\n * @memberof InfoAPIService\r\n * @return {object} promise\r\n */\n\n\n function sendCustomerIncident(flightDescription, question, description, imageStr) {\n var user = UserFactory.getUser();\n var call = $q.defer();\n var customerIncident = {\n flightDescription: flightDescription,\n question: question,\n description: description,\n image: imageStr\n };\n $http.post(apiUrl + '/customer/Incident', customerIncident, {\n 'Content-Type': 'application/json'\n }).then(function (responseData) {\n if (responseData == undefined || responseData.data == undefined || responseData.data.data == undefined) {\n var err = new Error();\n err.status = -1;\n var msg = \"ResponseData error in customer/Incident :\" + JSON.stringify(responseData);\n LogService.debug(msg, err);\n call.reject(err);\n return;\n }\n\n call.resolve(responseData);\n }, function (err) {\n call.reject(err);\n });\n return call.promise;\n }\n /**\r\n * Gets latest info for each duty in a crew route\r\n * @memberof InfoAPIService\r\n * @param {object} crewRouteDuty \r\n * @param {function} callback \r\n */\n\n\n function refreshCrewRoute(crewRouteDuty, callback) {\n var crewRouteInfo = {\n DutyNo: crewRouteDuty.DutyNo,\n DutyDay: crewRouteDuty.DutyDay,\n Route: crewRouteDuty.Route,\n From: crewRouteDuty.DutyBegin,\n To: crewRouteDuty.DutyEnd,\n FlightCourses: crewRouteDuty.Courses,\n CurrentDutyDate: crewRouteDuty.CurrentDutyDate\n }; //refresh route for the current day (Flight page)\n\n if (crewRouteDuty.CurrentDutyDate) {\n return $http.post(apiUrl + '/info/RefreshFlight', crewRouteInfo, {\n 'Content-Type': 'application/json'\n }).then(callback);\n } //Refresh whole Crew Route (Crew Route oage)\n else {\n return $http.post(apiUrl + '/info/RefreshCrewRoute', crewRouteInfo, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n }\n /**\r\n * Updates Route's Data Status depending on Refresh respond\r\n * @memberof InfoAPIService\r\n * @param {object} newDuty - Refresh respond\r\n * @param {array} dataStatus \r\n */\n\n\n function updateCrewRouteStatusSetter(dataStatus, crewRouteStatuses) {\n if (crewRouteStatuses.meals) {\n updateStatusSetter(dataStatus, [\"Meals\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Meals\"], \"N/A\", \"No available data\");\n }\n\n if (crewRouteStatuses.airportContacts) {\n updateStatusSetter(dataStatus, [\"Airport Contacts\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Airport Contacts\"], \"N/A\", \"No available data\");\n }\n\n if (crewRouteStatuses.groundServices) {\n updateStatusSetter(dataStatus, [\"Ground Services\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Ground Services\"], \"N/A\", \"No available data\");\n }\n\n if (crewRouteStatuses.aircraftDifferences) {\n updateStatusSetter(dataStatus, [\"Aircraft Differences\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Aircraft Differences\"], \"N/A\", \"No available data\");\n }\n\n if (crewRouteStatuses.campaigns) {\n updateStatusSetter(dataStatus, [\"Campaigns\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Campaigns\"], \"N/A\", \"No available data\");\n }\n\n if (crewRouteStatuses.airportHotels) {\n updateStatusSetter(dataStatus, [\"Hotels\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Hotels\"], \"N/A\", \"No available data\");\n }\n\n if (crewRouteStatuses.crewAimsMemos) {\n updateStatusSetter(dataStatus, [\"Aims Memos\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Aims Memos\"], \"N/A\", \"No available data\");\n }\n\n if (crewRouteStatuses.flightServiceEvents) {\n updateStatusSetter(dataStatus, [\"Flight Service Events\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Flight Service Events\"], \"N/A\", \"No available data\");\n }\n }\n /**\r\n * Updates Flight's Data Status depending on Refresh respond\r\n * @memberof InfoAPIService\r\n * @param {object} newDuty - Refresh respond\r\n * @param {array} dataStatus \r\n */\n\n\n function updateFlightStatusSetter(newDuty, dataStatus) {\n if (newDuty.FlightInfo) {\n updateStatusSetter(dataStatus, [\"Flight Status\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Flight Status\"], \"N/A\", \"No available data\");\n }\n\n if (newDuty.AircraftPositions && newDuty.AircraftPositions.length > 0) {\n updateStatusSetter(dataStatus, [\"Aircraft Movement\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Aircraft Movement\"], \"N/A\", \"No available data\");\n }\n\n if (newDuty.FlightInfo && newDuty.FlightInfo.crew && newDuty.FlightInfo.crew.length > 0) {\n updateStatusSetter(dataStatus, [\"Crew Info\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Crew Info\"], \"N/A\", \"No available data\");\n }\n\n if (newDuty.FlightInfo && newDuty.FlightInfo.crew && newDuty.FlightInfo.crew.length > 0 && newDuty.FlightInfo.crew.filter(function (x) {\n return x.PhoneNumber != null;\n }).length > 0) {\n updateStatusSetter(dataStatus, [\"Crew Contacts\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Crew Contacts\"], \"N/A\", \"No available data\");\n }\n\n if (newDuty.CabinServiceManagementLists && newDuty.CabinServiceManagementLists.length > 0 && newDuty.CabinServiceManagementLists[0].ConnectingFlights && newDuty.CabinServiceManagementLists[0].ConnectingFlights.length > 0) {\n updateStatusSetter(dataStatus, [\"Connections\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Connections\"], \"N/A\", \"No available data\");\n }\n\n if (newDuty.CabinServiceManagementLists && newDuty.CabinServiceManagementLists.length > 0 && newDuty.CabinServiceManagementLists[0].ConnectingFlights && newDuty.CabinServiceManagementLists.length > 0) {\n updateStatusSetter(dataStatus, [\"Pax Info\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Pax Info\"], \"N/A\", \"No available data\");\n }\n\n if (newDuty.LuggageCompliance && newDuty.LuggageCompliance.length > 0) {\n updateStatusSetter(dataStatus, [\"Luggage Info\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Luggage Info\"], \"N/A\", \"No available data\");\n }\n\n if (newDuty.TrainingCourses && newDuty.TrainingCourses.length > 0) {\n updateStatusSetter(dataStatus, [\"Training Info\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Training Info\"], \"N/A\", \"No available data\");\n }\n }\n /**\r\n * Updates Ground Duty's Data Status depending on Refresh respond\r\n * @memberof InfoAPIService\r\n * @param {array} newDuty - Refresh respond\r\n * @param {array} dataStatus \r\n */\n\n\n function updateGroundStatusSetter(newDuty, dataStatus) {\n if (newDuty) {\n updateStatusSetter(dataStatus, [\"Duty Info\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Duty\"], \"N/A\", \"No available data\");\n }\n\n if (newDuty && newDuty.RelatedGroundDuties && newDuty.RelatedGroundDuties.length > 1) {\n updateStatusSetter(dataStatus, [\"Instructors\"], \"SUCCESS\", \"Successfully updated\");\n updateStatusSetter(dataStatus, [\"Trainees\"], \"SUCCESS\", \"Successfully updated\");\n } else {\n updateStatusSetter(dataStatus, [\"Instructors\"], \"N/A\", \"No available data\");\n updateStatusSetter(dataStatus, [\"Trainees\"], \"N/A\", \"No available data\");\n }\n }\n /**\r\n * Changes the state of Data Status\r\n * @memberof InfoAPIService\r\n * @param {array} dataStatus \r\n * @param {array} array - Datatype to change\r\n * @param {string} status - New status\r\n * @param {string} text - New text\r\n */\n\n\n function updateStatusSetter(dataStatus, array, status, text) {\n var objsTochange = dataStatus.filter(function (x) {\n var res = array.filter(function (s) {\n return s == x.datatype;\n });\n return res.length > 0 ? true : false;\n });\n objsTochange.forEach(function (x) {\n x.status = status;\n x.text = text;\n var index = dataStatus.map(function (x) {\n return x.datatype;\n }).indexOf(x.datatype);\n dataStatus[index] = x;\n });\n }\n /**\r\n * Update Flight Info in Local Storage\r\n * @memberof InfoAPIService\r\n * @param {object} duty \r\n */\n\n\n function updateFlightLocalStorage(duty) {\n // save flight gates to local storage\n //var flightGates = duty.FlightGates;\n //FlightGateFactory.processUpdatedData(flightGates);\n //Update Aircraft positions\n if (duty.AircraftPositions != null && duty.AircraftPositions.length > 0) {\n AircaftPositionsFactory.updateAircraftPositionsToStorage(duty.AircraftPositions[0], duty.FlightInfo.FlightId);\n } // update flight to local storage\n\n\n FlightFactory.mergeFlightInfo(duty.FlightInfo, duty.ShowPaxNames); //Enrich flight info after sync\n\n SyncAPIService.updateCabinReportLocalEditFromSynch(); // update paxinfo to local storage\n\n if (duty.CabinServiceManagementLists && duty.CabinServiceManagementLists.length > 0) {\n PaxInfoFactory.updatePaxInfo(duty.CabinServiceManagementLists[0]);\n }\n\n if (duty.Campaigns && duty.Campaigns.FlightsCampaigns.length > 0) {\n if (duty.CabinServiceManagementLists) {\n CampaignFactory.updateSeatNoPaxAssignments(duty.Campaigns.FlightsCampaigns, duty.CabinServiceManagementLists);\n }\n\n CampaignFactory.mergeCampaigns(duty.Campaigns);\n }\n\n if (duty.CustomerEventHistory && duty.CustomerEventHistory.length) {\n CustomerEventHistoryFactory.refreshPassengerHistory(duty.CustomerEventHistory);\n } // update messages to local storage\n // MessageFactory.markReadAsSynched(duty.Messages);\n // MessageFactory.storeMessagesFromServer(duty.Messages);\n\n }\n /**\r\n * Update Ground Duty Info in Local Storage\r\n * @memberof InfoAPIService\r\n * @param {object} duty \r\n */\n\n\n function updateGroundDutyLocalStorage(duty) {\n GroundDutyFactory.mergeGroundDutyInfo(duty);\n }\n /**\r\n * Update Flight crew check-in Info in Local Storage\r\n * @memberof InfoAPIService\r\n * @param {object} duty \r\n */\n\n\n function updateCrewCheckIn(duty) {\n if (duty.FlightInfo) {\n FlightCheckInsFactory.updateFlightCrewCheckInToStorage(duty);\n }\n }\n /**\r\n * Update Philoxenia Questions for the current flight in Local Storage\r\n * @memberof InfoAPIService\r\n * @param {object} duty \r\n */\n\n\n function updatePhiloxeniaQuestions(duty) {\n if (duty.PhiloxeniaQuestions) {\n PhiloxeniaQuestionsFactory.updatePhiloxeniaQuestionsToStorage(duty.PhiloxeniaQuestions);\n }\n }\n }\n})();\n\"use strict\";\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.service(\"SyncAPIService\", SyncAPIService);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc service\r\n * @name SyncAPIService\r\n * @description \r\n * Generic Sync service which sends all your reports and gets all the latest data\r\n * @ngInject\r\n */\n\n function SyncAPIService($http, $q, apiUrl, FlightFactory, ReportGuidFactory, CabinReportTemplateItemFactory, SyncLogFactory, CabinReportLocalEditFactory, CrewRouteFactory, CrewMealFactory, CabinReportSendToServerFactory, CabinReportSyncResultFactory, AircraftTypeFactory, DataCleanerFactory, WaterUpliftActionFactory, ACSupplyFactory, SpecialMealSourceFactory, SpecialMealTypeFactory, CCMSFactory, TravelValueIncompleteReasonFactory, CCMSCrewPositionFactory, MessageFactory, LogService, CrewAssessmentTemplateFactory, CrewAssessmentFactory, CrewAssessmentCreatorFactory, UserFactory, AssessmentSyncResultFactory, SettingsMain, PaxInfoFactory, MemoFactory, FaqFactory, GroundDutyFactory, MemoImagesFactory, AircaftPositionsFactory, AimsCrewMemosFactory, IncompleteServicesSourceFactory, LeaveRequestFactory, CourseFactory, CampaignFactory, CrewHotelFactory, LuggageComplianceFactory, ScheduleAcknowledgeFactory, CrewCallFactory, PreviousDutyFactory, LogCallFactory, CheckInFactory, PhiloxeniaQuestionsFactory, TimeLogFactory, FlightCheckInsFactory, AnnualLeavesFactory, FlightDelaysFactory, ToolkitFactory, CustomerEventFactory, ExpiriesFactory, TraineeCoursesDetailsFactory, RequestFactory, WifiAvailabilityFactory, FlightServiceEventsFactory, PassengerMealServiceFactory, GroomingCategoriesFactory) {\n /**\r\n * Find if a relative old flight exists and if exists update it \r\n * @memberof SyncAPIService\r\n * @param {object} oldflight\r\n * @param {array} flights\r\n * @return {boolean} hasRelativeFlight\r\n */\n function relativeFlightMatcher(oldflight, flights) {\n var relativeFlights = [];\n var found = false;\n\n for (var i = 0; i < flights.length; i++) {\n if (oldflight.FlightNo == flights[i].FlightNo && oldflight.FlightDate == flights[i].FlightDate && oldflight.Departure == flights[i].Departure) {\n relativeFlights.push(flights[i]);\n found = true;\n break;\n }\n }\n\n if (!found) {\n var flight = null;\n var oldFlightNo = null;\n var lastDigit = oldflight.FlightNo.substr(oldflight.FlightNo.length - 1, 1);\n oldFlightNo = !isNaN(lastDigit) ? oldflight.FlightNo : oldflight.FlightNo.substr(0, oldflight.FlightNo.length - 1);\n\n for (var i = 0; i < flights.length; i++) {\n lastDigit = flights[i].FlightNo.substr(flights[i].FlightNo.length - 1, 1);\n flight = !isNaN(lastDigit) ? flights[i].FlightNo : flights[i].FlightNo.substr(0, flights[i].FlightNo.length - 1);\n\n if (oldFlightNo == flight && oldflight.FlightDate == flights[i].FlightDate && oldflight.Departure == flights[i].Departure) {\n relativeFlights.push(flights[i]);\n }\n }\n }\n\n if (relativeFlights.length == 1) {\n var cabinReportLocalEdit = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(oldflight.FlightId);\n cabinReportLocalEdit.FlightAimsId = relativeFlights[0].FlightAimsId;\n cabinReportLocalEdit.FlightId = relativeFlights[0].FlightId;\n CabinReportLocalEditFactory.setCabinReportToStorage(cabinReportLocalEdit);\n return true;\n } else if (relativeFlights.length > 1) {\n for (var i = 1; i < relativeFlights.length; i++) {\n for (var j = 0; j < relativeFlights.length - i; j++) {\n if (relativeFlights[j].FlightNo > relativeFlights[j + 1].FlightNo) {\n var a = relativeFlights[j];\n relativeFlights[j] = relativeFlights[j + 1];\n relativeFlights[j + 1] = a;\n }\n }\n }\n\n var cabinReportLocalEdit = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(oldflight.FlightId);\n cabinReportLocalEdit.FlightAimsId = relativeFlights[0].FlightAimsId;\n cabinReportLocalEdit.FlightId = relativeFlights[0].FlightId;\n CabinReportLocalEditFactory.setCabinReportToStorage(cabinReportLocalEdit);\n return true;\n } else {\n return false;\n }\n }\n\n ;\n return {\n /**\r\n * Send and get the latest information \r\n * @memberof SyncAPIService\r\n * @param {object} aimsId\r\n * @param {array} memoIdsToSend \r\n */\n doSync: function doSync(aimsId, memoIdsToSend) {\n //Clear timeLogs from local storage older than 2 days\n TimeLogFactory.cleanOldData(); //clear CrewMeal ratings from local storage that have timestamp older than 20 days\n\n DataCleanerFactory.deleteOldCrewMealsRatings(); // get the saved cabin reports\n\n var allSavedReports = CabinReportLocalEditFactory.getCabinReportsFromStorage();\n var IsAssessmentEnabled = SettingsMain.getIsAssessmentEnabled();\n var user = UserFactory.getUser();\n var lastLog = SyncLogFactory.getSyncLog();\n var lastSyncDate = lastLog.date; //Free to send all reports and assessments:\n\n var messagesToSend = MessageFactory.getUnsynchedReadMessages(); // keep only the ones that are ready to be sent\n\n var reportsToSend = CabinReportSendToServerFactory.getCompletedListFromCabinReportLocalEdits(allSavedReports);\n var assessmentsToSend = [];\n\n if (IsAssessmentEnabled && user.position == 'SA') {\n assessmentsToSend = CrewAssessmentFactory.getAssementsReadyToSend();\n }\n\n var passengersCampaignsToSend = CampaignFactory.getPaxAssignmentsFromStorage();\n var luggageCompliance = {\n luggageComplianceReports: LuggageComplianceFactory.getLuggageComplianceFromStorage().filter(function (x) {\n return !x.isSynced;\n })\n }; //Get call requests made while offline\n\n var phoneCallLog = {\n CrewCallReports: LogCallFactory.getLogCallsFromStorage()\n };\n var oneStopShopEvents = CustomerEventFactory.getUnsyncedCustomerEvents();\n\n var syncData = _defineProperty({\n \"SyncCabinReports\": reportsToSend,\n \"Messages\": messagesToSend,\n \"Assessments\": assessmentsToSend,\n \"Memos\": memoIdsToSend,\n \"PassengersCampaigns\": passengersCampaignsToSend,\n \"LuggageCompliance\": luggageCompliance,\n \"CrewCallLog\": phoneCallLog,\n \"LastSyncDate\": lastSyncDate,\n \"OneStopShopEvents\": oneStopShopEvents\n }, \"LastSyncDate\", lastSyncDate);\n\n var call = $q.defer();\n $http.post(apiUrl + '/sync', syncData, {\n 'Content-Type': 'application/json'\n }).then(function (responseData) {\n if (responseData == undefined || responseData.data == undefined || responseData.data.data == undefined || responseData.data.data.SyncCabinData == undefined) {\n var err = new Error();\n err.status = -1;\n var msg = \"ResponseData error in sync :\" + JSON.stringify(responseData);\n LogService.debug(msg, err);\n call.reject(err);\n return;\n }\n\n var response = responseData.data.data; //keep flights, will be used to retain a flight for old unsynched reports\n\n var orgFlights = FlightFactory.getFlightsFromStorage();\n var IsAssessmentEnabled = response.SyncCabinData.IsAssessmentEnabled;\n SettingsMain.setIsAssessmentEnabled(IsAssessmentEnabled); //Save schedule changes dates \n\n ScheduleAcknowledgeFactory.setAllScheduleChangesToStorage(response.SyncCabinData.ScheduleChanges);\n\n if (response.SyncCabinData.CrewCallLog && response.SyncCabinData.CrewCallLog.ResponseSuccess) {\n LogCallFactory.cleanLogsFromStorage();\n }\n\n var oneStopShop = response.SyncCabinData.OneStopShop; //save toolkit items\n\n if (oneStopShop.ToolkitItems) {\n ToolkitFactory.setToolkitItemsFromServer(oneStopShop.ToolkitItems);\n } //check OneStopShop CustomerEvents save status\n\n\n if (oneStopShop.CustomerEventsSynced) {\n oneStopShop.CustomerEventsSynced.forEach(function (event) {\n var localCustomerEvent = oneStopShopEvents.find(function (x) {\n return x.TemporaryId == event.TemporaryId;\n });\n localCustomerEvent.Synced = event.SaveSuccess; //No Treatment Id reset value\n\n if (localCustomerEvent.TreatmentId == null) localCustomerEvent.TreatmentId = -1;\n CustomerEventFactory.updateCustomerEvent(localCustomerEvent);\n });\n } //save training courses\n\n\n var rawTrainingCourses = response.SyncCabinData.TrainingCourses;\n var courses = [];\n rawTrainingCourses.forEach(function (course) {\n courses.push({\n Id: course.Id,\n Title: course.Title,\n HasLimitedInfo: true\n });\n });\n CourseFactory.setCoursesFromServer(courses); //clean crew member info\n\n var responseFlightIds = response.SyncCabinData.flights.map(function (x) {\n return x.FlightId;\n });\n CrewCallFactory.cleanOldData(responseFlightIds);\n PreviousDutyFactory.cleanOldData(responseFlightIds);\n PhiloxeniaQuestionsFactory.cleanOldData(responseFlightIds);\n LuggageComplianceFactory.cleanOldData(responseFlightIds);\n AircaftPositionsFactory.cleanOldData(responseFlightIds);\n FlightCheckInsFactory.cleanOldData(responseFlightIds); //TODO::move to refresh service:\n //DataCleaner for the pax info (indexedDb)\n\n var pendingFlightIds = CabinReportLocalEditFactory.getFlightIdsWithPendingReports();\n PaxInfoFactory.cleanOldDataPaxInfo(pendingFlightIds); //Data cleaner for the campaigns\n\n CampaignFactory.cleanOldCampaigns(pendingFlightIds); // //Data cleaner for the aims crew memos\n // AimsCrewMemosFactory.cleanOldAimsCrewMemos();\n\n AimsCrewMemosFactory.clearAimsCrewMemosFactoryFromStorage(); //Data cleaner for flight delays\n\n FlightDelaysFactory.cleanOldFlightDelays(responseFlightIds); //Clean old data for the flight service events\n\n FlightServiceEventsFactory.cleanOldDataServiceEvents(pendingFlightIds);\n GroomingCategoriesFactory.clearGroomingReportsFromStorage(); //Data cleaner for the customer events (flightDate of the event >= today - 5 days)\n // CustomerEventHistoryFactory.deleteOldHistoryEvents();\n // CustomerEventFactory.deleteOldCustomerEvents();\n // keep old assessments\n\n var oldAssessments = CrewAssessmentFactory.getCrewAssessmentsFromStorage(); // FlightGateFactory.processUpdatedData(response.SyncCabinData.flightGates);\n // clear existing server data\n\n DataCleanerFactory.deleteAllServerData();\n var fromSync = true;\n GroundDutyFactory.mergeGroundDutiesToStorage(response.SyncCabinData.groundDuties, fromSync);\n CrewRouteFactory.setCrewRoutesToStorage(response.SyncCabinData.CrewRoutes);\n CrewMealFactory.setCrewMealsToStorage(response.SyncCabinData.CateringCrewMeals);\n CrewHotelFactory.setCrewHotelsToStorage(response.SyncCabinData.CrewHotels);\n CheckInFactory.setCheckInInfoToStorage(response.CrewCheckInInfo);\n FlightServiceEventsFactory.setEventTypes(response.FlightServiceEventTypes);\n AnnualLeavesFactory.setAnnualLeavesToStorage(response.AnnualLeaves);\n ExpiriesFactory.setCrewExpiriesToStorage(response.CrewExpiries);\n AimsCrewMemosFactory.setAimsCrewMemosToStorage(response.SyncCabinData.aimsCrewMemos);\n WifiAvailabilityFactory.setRegistrationsToStorage(response.RegistrationsWithWifi); // PassengerMealServiceFactory.checkAndsetPassengerMealsServicesToStorage(response.PassengerMealServices);\n\n GroomingCategoriesFactory.setGroomingCategories(response.GroomingCategories);\n\n if (response.RosterRequestAncillaries) {\n RequestFactory.setSubmissionDeadlineDateToStorage(response.RosterRequestAncillaries.SubmissionEndDate);\n } //save, update or add memos\n\n\n var memos = response.SyncCabinData.memos;\n MemoFactory.setMemosFromServer(memos, memoIdsToSend, lastSyncDate);\n LeaveRequestFactory.saveLeaveRequestInformation(response.SyncCabinData.LeaveRequestInformation); //delete leftover memos \n\n var serverMemoIds = response.SyncCabinData.memoIds;\n\n for (var i = 0; i < serverMemoIds.length; i++) {\n MemoFactory.deleteMemoFromStorage(serverMemoIds[i]);\n }\n\n for (var i = 0; i < memos.length; i++) {\n MemoImagesFactory.deleteMemoImageByMemoId(memos[i].Id);\n }\n\n var images = response.SyncCabinData.Images;\n MemoImagesFactory.setImagesToServer(images);\n\n for (var i = 0; i < serverMemoIds.length; i++) {\n MemoImagesFactory.deleteMemoImageByMemoId(serverMemoIds[i]);\n } // save flight data to local storage\n\n\n var flightData = response.SyncCabinData.flights;\n var flights = FlightFactory.markScheduleChangedFlights(flightData, orgFlights);\n var assessments = response.SyncCabinData.assessments;\n var cabinReports = response.SyncCabinData.cabinReports;\n var assessmentTemplate = response.SyncCabinData.assessmentTemplate;\n CrewAssessmentTemplateFactory.setCrewAssessmentTemplateToStorage(assessmentTemplate);\n var reportGuids = response.SyncCabinData.guids;\n ReportGuidFactory.setReportGuidsToStorage(reportGuids); // save cabin report template to storage\n\n var cabinReportTemplateItems = response.SyncCabinData.cabinReportTemplate;\n CabinReportTemplateItemFactory.setCabinReportTemplateItemsToStorage(cabinReportTemplateItems); //store and sync messages\n\n var messages = response.SyncCabinData.messages;\n MessageFactory.markReadAsSynched(messages);\n MessageFactory.storeMessagesFromServer(messages); // save aircraft types to local storage\n\n var aircraftTypes = response.SyncCabinData.aircraftTypes;\n AircraftTypeFactory.setAircraftTypesToStorage(aircraftTypes); // save water uplift actions to local storage\n\n var wuas = response.SyncCabinData.waterUpliftActions;\n WaterUpliftActionFactory.setWaterUpliftActionsToStorage(wuas); // save ac supplies to local storage\n\n var acSupplies = response.SyncCabinData.acSupplies;\n ACSupplyFactory.setACSuppliesToStorage(acSupplies); // save special meal sources to local storage\n\n var specialMealSources = response.SyncCabinData.specialMealSources;\n SpecialMealSourceFactory.setSpecialMealSourcesToStorage(specialMealSources); // save special meal types to local storage\n\n var specialMealTypes = response.SyncCabinData.specialMealTypes;\n SpecialMealTypeFactory.setSpecialMealTypesToStorage(specialMealTypes); // save currencies to local storage\n\n /*var currencies = response.SyncCabinData.currencies;\r\n CurrencyFactory.setCurrenciesToStorage(currencies);*/\n //save all FAQs to local storage\n\n var FAQs = response.SyncCabinData.FAQPairs;\n FaqFactory.setFAQsFromServer(FAQs); // save currencies to local storage\n\n var travelReasons = response.SyncCabinData.travelValueIncompleteReasons;\n TravelValueIncompleteReasonFactory.setReasonsToStorage(travelReasons); // save Incomplete In-Flight Services Reasons and Types:\n\n var incompleteInFlightServiceListOfValues = response.SyncCabinData.incompleteInFlightServiceListOfValues;\n IncompleteServicesSourceFactory.setIncompleteInFlightServiceListOfValues(incompleteInFlightServiceListOfValues); // log the sync user and date\n\n SyncLogFactory.setSyncLog(aimsId, response.SyncCabinData.version, response.SyncCabinData.toDate); // save ccms to local storage\n\n var ccms = response.SyncCabinData.ccms;\n CCMSFactory.setCCMSToStorage(ccms);\n var traineeCourses = response.SyncCabinData.TraineeCourses;\n TraineeCoursesDetailsFactory.setTraineeCoursesToStorage(traineeCourses);\n var traineeFlightCourses = response.SyncCabinData.TraineeFlightCourses;\n TraineeCoursesDetailsFactory.setTraineeFlightCoursesToStorage(traineeFlightCourses); // get the sync results\n\n var syncResults = CabinReportSyncResultFactory.fromObjectList(response.SyncCabinData.reportResults);\n var flight; // mark sent reports as synched\n\n for (var j = 0; j < reportsToSend.length; j++) {\n var syncResult = CabinReportSyncResultFactory.getSyncResult(syncResults, reportsToSend[j].ReportGuid);\n\n if (syncResult != null) {\n if (syncResult.success) {\n CabinReportLocalEditFactory.markReportAsSynched(reportsToSend[j].ReportGuid);\n syncResult.Result = 'Successfully submitted';\n } else {\n syncResult.Result = 'Submission error';\n } // find flight and append report fields\n\n\n flight = null;\n\n if (orgFlights != null) {\n for (i = 0; i < orgFlights.length; i++) {\n if (orgFlights[i].FlightId != null && orgFlights[i].FlightId == reportsToSend[j].FlightId || orgFlights[i].FlightAimsId != null && orgFlights[i].FlightAimsId == reportsToSend[j].FlightAimsId) {\n flight = orgFlights[i];\n break;\n }\n }\n } //var flight = FlightFactory.getFlightFromStorage(reportsToSend[j].FlightAimsId);\n\n\n if (flight != null) {\n syncResult.FlightAimsId = flight.FlightAimsId;\n syncResult.FlightId = flight.FlightId;\n syncResult.ScheduledDepartureDateUTC = flight.ScheduledDepartureDateUTC;\n syncResult.FlightNo = flight.FlightNo;\n syncResult.Departure = flight.Departure;\n syncResult.Arrival = flight.Arrival;\n syncResult.ScheduledDepartureTimeUTC = flight.ScheduledDepartureTimeUTC;\n syncResult.AcTailNo = flight.AcTailNo;\n }\n }\n } // save the sync results\n\n\n CabinReportSyncResultFactory.setCabinReportSyncResultsToStorage(syncResults);\n AssessmentSyncResultFactory.setAssessmentSyncResultsToStorage(response.SyncCabinData.assessmentResults); // delete local flights with no local reports\n\n DataCleanerFactory.deleteOrphanedLocalFlights(); //**************** ADD CODE TO KEEP FLIGHTS IF THEY STIL HAVE AN NOT SYCNHED REPORT *********************//\n //find flight ids used by draft reports\n //**************** ADD CODE TO KEEP FLIGHTS IF THEY STIL HAVE AN NOT SYCNHED REPORT *********************//\n //find flight ids used by draft reports\n\n if (allSavedReports) {\n var verifyFlightAimsIds = [];\n var verifyFlightIds = [];\n\n for (var i = 0; i < allSavedReports.length; i++) {\n if (allSavedReports[i].Status == 'draft' || allSavedReports[i].Status == 'completed') verifyFlightAimsIds.push(allSavedReports[i].FlightAimsId);\n verifyFlightIds.push(allSavedReports[i].FlightId);\n } //search these ids into the newly received flights\n\n\n if (verifyFlightAimsIds.length > 0) {\n var missingIds = [];\n var missingAimsIds = [];\n var found, id, aimsId;\n\n for (var i = 0; i < verifyFlightAimsIds.length; i++) {\n found = false;\n aimsId = verifyFlightAimsIds[i];\n id = verifyFlightIds[i];\n\n for (var f = 0; f < flights.length; f++) {\n if (flights[f].FlightId != null && flights[f].FlightId == id || flights[f].FlightAimsId != null && flights[f].FlightAimsId == aimsId) {\n found = true;\n break;\n }\n }\n\n if (!found) missingIds.push(id);\n missingAimsIds.push(aimsId);\n } //search missing flights in flights stored before sync\n\n\n if (orgFlights) {\n for (var m = 0; m < missingIds.length; m++) {\n id = missingIds[m];\n aimsId = missingAimsIds[m];\n\n for (var o = 0; o < orgFlights.length; o++) {\n if (orgFlights[o].FlightId != null && orgFlights[o].FlightId == id || orgFlights[o].FlightAimsId != null && orgFlights[o].FlightAimsId == aimsId) {\n if (!relativeFlightMatcher(orgFlights[o], flights)) {\n flights.push(orgFlights[o]);\n }\n\n break;\n }\n }\n }\n }\n }\n }\n /* //keep assessments when their route exists in flight\r\n CrewAssessmentFactory.storeAllSyncAssessments(orgAssessments,assessments,flights);*/\n\n\n FlightFactory.storeFlightsWithReportsAndMessages(flights, cabinReports, messages); //Keep the old assessment and create assessment to the routes that are left\n\n var assessmentsToCreate = [];\n var finalAssessments = [];\n assessments = assessments ? assessments : [];\n\n for (var i = 0; i < assessments.length; i++) {\n var isExists = false;\n\n for (var j = 0; j < oldAssessments.length; j++) {\n if (oldAssessments[j].Route == assessments[i].Route && oldAssessments[j].DutyDate == assessments[i].DutyDate) {\n var oldAssessment = CrewAssessmentFactory.updateCrewAssessment(oldAssessments[j], assessments[i]);\n finalAssessments.push(oldAssessment);\n isExists = true;\n break;\n }\n }\n\n if (!isExists) {\n assessmentsToCreate.push(assessments[i]);\n }\n } //keep assessment for old reports\n\n\n for (var i = 0; i < oldAssessments.length; i++) {\n var IsAssessmentExists = false;\n\n for (var j = 0; j < finalAssessments.length; j++) {\n if (oldAssessments[i].Id == finalAssessments[j].Id) {\n IsAssessmentExists = true;\n break;\n }\n }\n\n if (!IsAssessmentExists) {\n if (CabinReportLocalEditFactory.IsExistForRouteDutyDate(oldAssessments[i].Route, oldAssessments[i].DutyDate)) {\n finalAssessments.push(oldAssessments[i]);\n }\n }\n }\n\n var newAssessments = CrewAssessmentCreatorFactory.createCrewAssessments(assessmentsToCreate);\n finalAssessments = finalAssessments.concat(newAssessments);\n CrewAssessmentFactory.setCrewAssessmentsToStorage(finalAssessments);\n CrewAssessmentFactory.storeFlightsWithAssessments();\n CrewAssessmentFactory.storeCrewRoutesWithAssessments(); //TimeLogFactory.timeLogToStorage(timeLog, response.SyncCabinData.timelog);\n // return true\n\n call.resolve(responseData);\n }, function (err) {\n call.reject(err);\n });\n return call.promise;\n },\n\n /**\r\n * Update local reports from synced Fligths \r\n * @memberof SyncAPIService\r\n */\n updateCabinReportLocalEditFromSynch: function updateCabinReportLocalEditFromSynch() {\n var cabinReportLocalEdits = CabinReportLocalEditFactory.getCabinReportsFromStorage();\n\n if (cabinReportLocalEdits != undefined && cabinReportLocalEdits != null) {\n for (var i = 0; i < cabinReportLocalEdits.length; i++) {\n var flight = FlightFactory.getFlightFromStorage(cabinReportLocalEdits[i].FlightId, cabinReportLocalEdits[i].FlightAimsId);\n\n if ((cabinReportLocalEdits[i].Status == \"draft\" || cabinReportLocalEdits[i].Status == \"completed\") && flight) {\n //console.log(cabinReportLocalEdits[i].FlightAimsId);\n cabinReportLocalEdits[i].Departure = flight.Departure;\n cabinReportLocalEdits[i].Arrival = flight.Arrival;\n cabinReportLocalEdits[i].AcType = flight.AcType;\n cabinReportLocalEdits[i].AcTailNo = flight.AcTailNo;\n cabinReportLocalEdits[i].FlightNo = flight.FlightNo;\n cabinReportLocalEdits[i].DepartureICAO = flight.DepartureICAO;\n cabinReportLocalEdits[i].DepartureCountry = flight.DepartureCountry;\n cabinReportLocalEdits[i].DepartureName = flight.DepartureName;\n cabinReportLocalEdits[i].ArrivalICAO = flight.ArrivalICAO;\n cabinReportLocalEdits[i].ArrivalCountry = flight.ArrivalCountry;\n cabinReportLocalEdits[i].ArrivalName = flight.ArrivalName;\n cabinReportLocalEdits[i].ScheduledDepartureDateUTC = flight.ScheduledDepartureDateUTC;\n cabinReportLocalEdits[i].ScheduledDepartureTimeUTC = flight.ScheduledDepartureTimeUTC;\n cabinReportLocalEdits[i].ScheduledDeparture = flight.ScheduledDeparture;\n cabinReportLocalEdits[i].BookedC = flight.BookedC;\n cabinReportLocalEdits[i].BookedY = flight.BookedY;\n cabinReportLocalEdits[i].BookedInf = flight.BookedInf;\n cabinReportLocalEdits[i].BookedPad = flight.BookedPad;\n cabinReportLocalEdits[i].BookedChld = flight.BookedChld;\n cabinReportLocalEdits[i].ActualC = flight.ActualC;\n cabinReportLocalEdits[i].ActualY = flight.ActualY;\n cabinReportLocalEdits[i].ActualInf = flight.ActualInf;\n cabinReportLocalEdits[i].ActualPad = flight.ActualPad;\n cabinReportLocalEdits[i].ActualChld = flight.ActualChld;\n cabinReportLocalEdits[i].DepartureGate = flight.DepartureGate;\n cabinReportLocalEdits[i].DepartureTimezone = flight.DepartureTimezone;\n cabinReportLocalEdits[i].ArrivalTimezone = flight.ArrivalTimezone;\n cabinReportLocalEdits[i].CallSign = flight.CallSign;\n cabinReportLocalEdits[i].ScheduledArrival = flight.ScheduledArrival;\n cabinReportLocalEdits[i].Route = flight.Route;\n cabinReportLocalEdits[i].DutyDate = flight.DutyDate;\n var manualCCMSCrewPositions = [];\n\n for (var k = 0; k < cabinReportLocalEdits[i].CCMSCrewPositions.length; k++) {\n if (cabinReportLocalEdits[i].CCMSCrewPositions[k].IsManual) {\n manualCCMSCrewPositions.push(cabinReportLocalEdits[i].CCMSCrewPositions[k]);\n }\n }\n\n cabinReportLocalEdits[i].crew = flight.crew;\n var newCCMSCrewPositions = [];\n var IsNew;\n var changeStatus = false;\n\n for (var h = 0; h < cabinReportLocalEdits[i].crew.length; h++) {\n if (cabinReportLocalEdits[i].crew[h].isDHC == false && cabinReportLocalEdits[i].crew[h].position != 'CP' && cabinReportLocalEdits[i].crew[h].position != 'FO') {\n var crewPosition = CCMSCrewPositionFactory.createNew();\n crewPosition.CrewId = cabinReportLocalEdits[i].crew[h].aimsId;\n crewPosition.Initials = cabinReportLocalEdits[i].crew[h].shortname;\n crewPosition.Name = cabinReportLocalEdits[i].crew[h].name;\n crewPosition.Position = cabinReportLocalEdits[i].crew[h].position;\n crewPosition.IsManual = false;\n IsNew = false;\n\n for (var k = 0; k < cabinReportLocalEdits[i].CCMSCrewPositions.length; k++) {\n if (flight.crew[h].aimsId == cabinReportLocalEdits[i].CCMSCrewPositions[k].CrewId) {\n crewPosition.CCMS = cabinReportLocalEdits[i].CCMSCrewPositions[k].CCMS;\n crewPosition.CrewComments = cabinReportLocalEdits[i].CCMSCrewPositions[k].CrewComments;\n crewPosition.AdditionalFeedbackId = cabinReportLocalEdits[i].CCMSCrewPositions[k].AdditionalFeedbackId;\n crewPosition.Route = cabinReportLocalEdits[i].Route;\n\n if (crewPosition.CCMS == null) {\n IsNew = true;\n }\n\n break;\n }\n }\n\n if (IsNew) {\n changeStatus = true;\n }\n\n newCCMSCrewPositions.push(crewPosition);\n }\n }\n\n if (changeStatus) {\n cabinReportLocalEdits[i].Status = \"draft\";\n }\n\n cabinReportLocalEdits[i].CCMSCrewPositions = newCCMSCrewPositions.concat(manualCCMSCrewPositions);\n }\n }\n\n CabinReportLocalEditFactory.setCabinReportsToStorage(cabinReportLocalEdits);\n }\n }\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('SynchCtrl', SynchCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SynchCtrl\r\n * @description \r\n * Manage Sync View\r\n * @ngInject\r\n */\n\n function SynchCtrl($scope, $uibModalInstance, UserFactory, CabinReportLocalEditFactory, SyncAPIService, SyncLogFactory, ReportGuidFactory, CabinReportSyncResultFactory, DataCleanerFactory, MessageFactory, CrewAssessmentFactory, AssessmentSyncResultFactory, SettingsMain, $route, $timeout, MemoFactory, FlightFactory, CabinReportRestoreFactory, CampaignFactory, LuggageComplianceFactory) {\n var IsAssessmentEnabled = SettingsMain.getIsAssessmentEnabled();\n var user = UserFactory.getUser();\n var lastLog = SyncLogFactory.getSyncLog();\n var reportstobesynched = CabinReportLocalEditFactory.getCabinReportLocalEditThatNeedToBeSynched();\n\n if (user.position == 'SA') {\n if (IsAssessmentEnabled) {\n var isSA = true;\n var assessmentstobesynched = CrewAssessmentFactory.getAssementsReadyToSend();\n }\n } else {\n var isSA = false;\n var assessmentstobesynched = [];\n }\n\n $scope.syncResultsVisible = false;\n $scope.isSynching = false; // setup the grid\n\n $scope.syncTableData = reportstobesynched;\n $scope.IsSA = isSA; // get the last sync date\n\n $scope.isFirstSync = false;\n $scope.isTooOldSync = false;\n $scope.lastSyncDate = '-';\n $scope.syncVersion = '1.2'; // get the report credits\n\n $scope.reportCredits = ReportGuidFactory.getRemainingReportGuids(); // display the number of reports to synch\n\n $scope.number_of_reports_to_sync = $scope.syncTableData.length;\n $scope.syncAssessmentTableData = CrewAssessmentFactory.getAssementsReadyToSend();\n $scope.number_of_assessments_to_sync = $scope.syncAssessmentTableData.length;\n\n if (lastLog == null) {\n $scope.isFirstSync = true;\n } else {\n if (lastLog.date != null) {\n $scope.lastSyncDate = new Date(lastLog.date).toUTC().toString('dd-MM-yyyy HH:mm') + ' UTC';\n if (Date.today().add(-3).days().toUTC().isAfter(new Date(lastLog.date).toUTC())) $scope.isTooOldSync = true;\n }\n\n if (lastLog.version != null) $scope.syncVersion = lastLog.version;\n }\n\n $scope.doSynch = doSynch;\n $scope.ok = ok;\n $scope.cancel = cancel;\n $scope.showReportSyncResults = showReportSyncResults;\n $scope.showAssessmentSyncResults = showAssessmentSyncResults;\n $scope.syncResultsOk = syncResultsOk;\n $scope.showSynchError = showSynchError;\n /**\r\n * Start Synch functionality\r\n * @memberof SynchCtrl\r\n */\n\n function doSynch() {\n //Save reports to indexedDB before the sync\n CabinReportRestoreFactory.backUpReports(); //waiting for memoIds before we sync\n\n MemoFactory.getStoredMemosIds(function (memoIdsToSend) {\n // get the user\n var user = UserFactory.getUser(); // call the remote service for data\n\n var q = SyncAPIService.doSync(user.aimsId, memoIdsToSend);\n $scope.isSynching = true;\n q.then(function (response) {\n $scope.isSynching = false;\n\n if ($scope.number_of_reports_to_sync > 0) {\n $scope.showReportSyncResults('synched');\n } else {\n $scope.showReportSyncResults('synched-no-send');\n }\n\n $scope.showAssessmentSyncResults();\n DataCleanerFactory.deleteSynchedLocalCabinReports();\n DataCleanerFactory.deleteOrphanedLocalReports();\n DataCleanerFactory.deleteOrphanedCustomerEvents();\n SyncAPIService.updateCabinReportLocalEditFromSynch();\n FlightFactory.initializeFlights();\n MemoFactory.markGroundDutiesUnread();\n $scope.campaigns = CampaignFactory.syncResultFormat(response.data.data.SyncCabinData.Campaigns);\n $scope.luggageCompliance = LuggageComplianceFactory.syncResultFormat(response.data.data.SyncCabinData.LuggageCompliance);\n });\n q[\"catch\"](function (err) {\n $scope.isSynching = false;\n\n if (err.status == -1) {\n $scope.errorName = \"There were problems during the server synchronization. Please try again.\";\n } else if (err.status != 401) {\n // if an error was encountered display an error message\n $scope.errorName = \"Could not reach the remote server. Please connect to the Internet and try again.\";\n } else {\n $uibModalInstance.close('');\n }\n });\n });\n }\n /**\r\n * show Report Sync Results\r\n * @memberof SynchCtrl\r\n */\n\n\n function showReportSyncResults() {\n $scope.syncResultsVisible = true; // get the sync results\n\n $scope.syncResultsTableData = CabinReportSyncResultFactory.getCabinReportSyncResultsFromStorage();\n $scope.syncSuccesses = CabinReportSyncResultFactory.getSuccesses($scope.syncResultsTableData);\n $scope.syncFailures = CabinReportSyncResultFactory.getFailures($scope.syncResultsTableData);\n\n if ($scope.syncResultsTableData != null) {\n $scope.reports_to_sync = $scope.syncResultsTableData.length;\n } else {\n $scope.reports_to_sync = 0;\n }\n\n if ($scope.syncSuccesses == 1) {\n $scope.sync_successes_descr = 'Cabin Report was';\n } else {\n $scope.sync_successes_descr = 'Cabin Reports were';\n }\n\n if ($scope.syncFailures == 1) {\n $scope.sync_failures_descr = 'Cabin Report was';\n } else {\n $scope.sync_failures_descr = 'Cabin Reports were';\n }\n\n $scope.unreadMessages = MessageFactory.getCountOfUnreadMessages();\n }\n /**\r\n * show Assessment Sync Results\r\n * @memberof SynchCtrl\r\n */\n\n\n function showAssessmentSyncResults() {\n $scope.syncResultsVisible = true; // get the sync results\n\n $scope.syncAssessmentResultsTableData = AssessmentSyncResultFactory.getAssessmentSyncResultsFromStorage();\n $scope.syncAssessmentSuccesses = AssessmentSyncResultFactory.getSuccesses($scope.syncAssessmentResultsTableData);\n $scope.syncAssessmentFailures = AssessmentSyncResultFactory.getFailures($scope.syncAssessmentResultsTableData);\n\n if ($scope.syncAssessmentResultsTableData != null) {\n $scope.assessments_to_sync = $scope.syncAssessmentResultsTableData.length;\n } else {\n $scope.assessments_to_sync = 0;\n }\n\n if ($scope.syncAssessmentSuccesses == 1) {\n $scope.sync_assessment_successes_descr = 'Crew Feedback was';\n } else {\n $scope.sync_assessment_successes_descr = 'Crew Feedbacks were';\n }\n\n if ($scope.syncAssessmentFailures == 1) {\n $scope.sync_assessment_failures_descr = 'Crew Feedbacks was';\n } else {\n $scope.sync_assessment_failures_descr = 'Crew Feedbacks were';\n }\n }\n /**\r\n * Close sync Result modal and update cache.\r\n * @memberof SynchCtrl\r\n */\n\n\n function syncResultsOk() {\n $uibModalInstance.close('synched');\n $route.reload(); // get cache\n }\n /**\r\n * Show submision sync error\r\n * @memberof SynchCtrl\r\n */\n\n\n function showSynchError(message) {\n bootbox.dialog({\n message: message,\n title: \"Submission error\",\n buttons: {\n cancel: {\n label: \"OK\",\n className: \"btn-default\",\n callback: function callback() {}\n }\n }\n });\n }\n /**\r\n * Close modal and update cache.\r\n * @memberof SynchCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close('cancel'); // get cache\n }\n /**\r\n * Close modal\r\n * @memberof SynchCtrl\r\n */\n\n\n function ok() {\n $uibModalInstance.close('');\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('SyncLogFactory', SyncLogFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SyncLogFactory\r\n * @description \r\n * Add, update or delete synchronization log\r\n * @ngInject\r\n */\n\n function SyncLogFactory($log, GenericService) {\n /**\r\n * Initialize the Sync Log\r\n * @memberof SyncLogFactory\r\n */\n function SyncLog() {\n var self = this;\n this.userAimsId = null;\n this.date = null;\n this.version = null;\n this.lastShow = null;\n this.isUpdated = false;\n this.lastScheduleDate = null;\n this.forceSync = false; //showing the sync dialog\n\n this.canShowSync = function () {\n var can = false;\n if (this.lastShow == null) can = true;else if (new Date().add(-10).minutes().toUTC().isAfter(new Date(this.lastShow).toUTC())) {\n can = true;\n }\n return can;\n };\n }\n\n var objType = 'syncLog';\n var objCallback = SyncLog;\n var service = {\n getSyncLog: getSyncLog,\n setSyncLog: setSyncLog,\n updateSyncVersion: updateSyncVersion,\n setLastShow: setLastShow,\n clearSyncLog: clearSyncLog,\n getLastScheduleDate: getLastScheduleDate,\n setLastScheduleDate: setLastScheduleDate,\n forceSync: forceSync\n };\n /**\r\n * Get Sync Log\r\n * @memberof SyncLogFactory\r\n * @return {object} syncLog \r\n */\n\n function getSyncLog() {\n return GenericService.getOne(objType, objCallback);\n }\n /**\r\n * Set Sync Log\r\n * @memberof SyncLogFactory\r\n * @param {string} userAimsId \r\n * @param {string} version \r\n * @param {string} lastScheduleDate \r\n */\n\n\n function setSyncLog(userAimsId, version, lastScheduleDate) {\n var newLog = new SyncLog();\n newLog.userAimsId = userAimsId;\n newLog.date = new Date();\n newLog.version = version;\n newLog.lastShow = new Date();\n newLog.isUpdated = false;\n newLog.forceSync = false;\n newLog.lastScheduleDate = new Date(lastScheduleDate).getTime();\n GenericService.saveOne(newLog, objType, objCallback);\n }\n /**\r\n * Update Sync Log version\r\n * @memberof SyncLogFactory\r\n * @param {string} version \r\n */\n\n\n function updateSyncVersion(version) {\n var syncLog = SyncLog.getSyncLog();\n syncLog.version = version;\n syncLog.isUpdated = true;\n GenericService.saveOne(syncLog, objType, objCallback);\n }\n /**\r\n * Set last show of molal\r\n * @memberof SyncLogFactory\r\n */\n\n\n function setLastShow() {\n var log = getSyncLog();\n if (log == null) log = new SyncLog();\n log.lastShow = new Date();\n GenericService.saveOne(log, objType, objCallback);\n }\n /**\r\n * Clear Sync Log\r\n * @memberof SyncLogFactory\r\n */\n\n\n function clearSyncLog() {\n GenericService.removeAll(objType, objCallback);\n }\n /**\r\n * Get Last Schedule Date\r\n * @memberof SyncLogFactory\r\n * @return {string} date \r\n */\n\n\n function getLastScheduleDate() {\n var syncLog = getSyncLog();\n\n if (syncLog == null) {\n return null;\n } else {\n return syncLog.lastScheduleDate;\n }\n }\n /**\r\n * Set Last Schedule Date\r\n * @memberof SyncLogFactory\r\n * @param {string} date \r\n */\n\n\n function setLastScheduleDate(date) {\n var log = getSyncLog();\n if (log == null) log = new SyncLog();\n log.lastScheduleDate = date;\n GenericService.saveOne(log, objType, objCallback);\n }\n /**\r\n * Forces Sync Modal to appear\r\n * @memberof SyncLogFactory\r\n */\n\n\n function forceSync() {\n var syncLog = getSyncLog();\n syncLog.forceSync = true;\n GenericService.saveOne(syncLog, objType, objCallback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('TicketCtrl', TicketCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name TicketCtrl\r\n * @description \r\n * Send a ticket\r\n * @ngInject\r\n */\n\n function TicketCtrl($scope, UserFactory, PhotoFactory, TicketAPIService, $location, $uibModal, version, CabinReportRestoreFactory) {\n var user = UserFactory.getUser();\n user;\n $scope.submitted = false;\n $scope.ticket = {};\n $scope.ticket.photos = [];\n $scope.maximumAttatchedPhotos = 3;\n $scope.showMaxImages = false;\n $scope.quality = 0.6;\n $scope.width = 1280;\n $scope.height = 1024;\n $scope.sizeLimitKb = 1000;\n $scope.imageTooLargeMsg = false;\n $scope.gotoHome = gotoHome;\n $scope.state = 'ticket';\n $scope.restoreReportsAction = restoreReportsAction;\n appendPhoto();\n $scope.sendTicket = sendTicket;\n $scope.imageUploaded = imageUploaded;\n $scope.removePhoto = removePhoto;\n $scope.ticket.Version = version;\n\n if (user && user.aimsId && UserFactory.isLoggedIn()) {\n $scope.ticket.aimsId = user.aimsId;\n $scope.isLogged = true;\n }\n /**\r\n * Redirects to home view\r\n * @memberof TicketCtrl\r\n */\n\n\n function gotoHome() {\n $location.path(\"/\");\n }\n /**\r\n * Send application ticket information\r\n * @memberof TicketCtrl\r\n */\n\n\n function sendTicket() {\n $scope.submitted = true;\n\n if (validateTicket()) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Dialogs/dlgTicketSend.html',\n controller: 'TicketModalCtrl',\n size: 'md',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n ticket: function ticket() {\n return $scope.ticket;\n }\n }\n });\n modalInstance.result.then(function () {\n $location.path(\"/\");\n });\n }\n }\n /**\r\n * Validate ticket before sending\r\n * @memberof TicketCtrl\r\n * @return {boolean} isValid\r\n */\n\n\n function validateTicket() {\n var isValid = false;\n\n if ($scope.ticket.aimsId && $scope.ticket.title && $scope.ticket.description) {\n isValid = true;\n }\n\n return isValid;\n }\n /**\r\n * is Image Too Large \r\n * @memberof TicketCtrl\r\n * @return {boolean} isValid\r\n */\n\n\n function isImageTooLarge(image) {\n var isLarge = false;\n\n if (image && image.dataURL != null) {\n isLarge = image.dataURL.length > $scope.sizeLimitKb * 1024;\n }\n\n return isLarge;\n }\n /**\r\n * Upload Image\r\n * @memberof TicketCtrl\r\n */\n\n\n function imageUploaded(data, img) {\n //console.log('told of a new image', imageResult, this.imageBrowsed, $scope.imageBrowsed);\n var imageResult = data; //$scope.imageBrowsed;\n\n if (imageResult != null) {\n if (isImageTooLarge(data)) {\n $scope.imageTooLargeMsg = true;\n } else {\n $scope.imageTooLargeMsg = false;\n img.PhotoData = imageResult.dataURL;\n img.FileType = imageResult.fileType || imageResult.file.type;\n img.Remarks = imageResult.fileName;\n appendPhoto();\n }\n }\n }\n /**\r\n * Allows to add more photos up to the maximum number allowed\r\n * @memberof TicketCtrl\r\n */\n\n\n function appendPhoto() {\n if ($scope.ticket.photos.length < $scope.maximumAttatchedPhotos) {\n var photo = PhotoFactory.createNew();\n $scope.ticket.photos.push(photo);\n } else {\n $scope.showMaxImages = true;\n }\n }\n /**\r\n * Remove Selected photo\r\n * @memberof TicketCtrl\r\n * @param {object} photo\r\n */\n\n\n function removePhoto(photo) {\n PhotoFactory.deleteFromList(photo, $scope.ticket.photos);\n\n if ($scope.showMaxImages) {\n appendPhoto();\n }\n\n $scope.showMaxImages = false;\n }\n /**\r\n * Restore lost reports process and return list of FlightNo for each restored report into a modal.\r\n * @memberof flightFooter \r\n */\n\n\n function restoreReportsAction() {\n CabinReportRestoreFactory.restoreReports(function (restoreResults) {\n var bootboxMessage = \"\";\n\n if (restoreResults != 'undefined' && restoreResults.length > 0) {\n bootboxMessage = \"

Lost reports have been restored successfully for the following flights:

\";\n restoreResults.forEach(function (x) {\n bootboxMessage += \"
\";\n bootboxMessage += \"- \" + x;\n });\n } else {\n bootboxMessage = \"No missing reports have been found\";\n }\n\n bootbox.alert({\n title: \"Retrieve lost reports\",\n message: bootboxMessage\n });\n });\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.service(\"TicketAPIService\", TicketAPIService);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc service\r\n * @name TicketAPIService\r\n * @description \r\n * Manages the api calls for the Ticket report system\r\n * @ngInject\r\n */\n\n function TicketAPIService($http, $q, apiUrl, localStorageMD5Service, LogService) {\n /**\r\n * Send Ticket2\r\n * @memberof TicketAPIService\r\n * @return {object} promise\r\n */\n function sendTicket(ticket) {\n var call = $q.defer();\n ticket.DeviceData = getStoredValues();\n $http.post(apiUrl + '/ticket', ticket, {\n 'Content-Type': 'application/json'\n }).then(function (responseData) {\n if (responseData == undefined || responseData.data == undefined || responseData.data.data == undefined) {\n var err = new Error();\n err.status = -1;\n var msg = \"ResponseData error while sending a ticket :\" + JSON.stringify(responseData);\n LogService.debug(msg, err);\n call.reject(err);\n } else {\n // return true\n call.resolve(responseData);\n }\n }, function (err) {\n call.reject(err);\n });\n return call.promise;\n }\n /**\r\n * Get all values from localstorage\r\n * @memberof TicketAPIService\r\n */\n\n\n function getStoredValues() {\n var values = [];\n var keys = localStorageMD5Service.keys();\n\n if (keys) {\n var key, value, sizeActual, error;\n\n for (var i = 0; i < keys.length; i++) {\n key = keys[i];\n\n try {\n value = localStorageMD5Service.get(key);\n value = angular.toJson(value);\n sizeActual = localStorageMD5Service.usedSize(key);\n error = null;\n } catch (e) {\n error = e.message || e.errorMessage;\n }\n\n values.push({\n key: key,\n value: value,\n error: error,\n size: value ? value.length : 0,\n sizeActual: sizeActual\n });\n }\n }\n\n return values;\n }\n\n return {\n sendTicket: sendTicket\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('TicketModalCtrl', TicketModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name TicketCtrl\r\n * @description \r\n * Report a bug of the application\r\n * @ngInject\r\n */\n\n function TicketModalCtrl($scope, $uibModalInstance, $timeout, TicketAPIService, LogService, PhotoFactory, ticket) {\n $scope.successful = false;\n $scope.error = false;\n var q = TicketAPIService.sendTicket(ticket);\n q.then(function (responseData) {\n if (responseData.data.data) {\n $scope.successful = true;\n } else {\n $scope.error = true;\n }\n\n $timeout(function () {\n $uibModalInstance.close();\n }, 3000);\n }, function () {\n $scope.error = true;\n $timeout(function () {\n $uibModalInstance.close();\n }, 3000);\n });\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('additionalTrainingReadOnly', additionalTrainingReadOnly);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name additionalTrainingReadOnly\r\n * @restrict E\r\n * @description\r\n * Implementation of additional Training ReadOnly\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function additionalTrainingReadOnly() {\n function link(scope, element, attrs) {}\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/TrainingReadOnly/additional-training-read-only.tpl.html',\n scope: {\n traineeSession: \"=\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('competencesReadOnly', competencesReadOnly);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name competencesReadOnly\r\n * @restrict E\r\n * @description\r\n * Implementation of competences read only\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function competencesReadOnly() {\n function link(scope, element, attrs) {\n if (scope.trainee.Competences) {\n scope.trainee.Competences.forEach(function (competence) {\n competence.hasSelectedSubCompetence = competence.SubCompetences.some(function (x) {\n return x.Selected;\n });\n });\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/TrainingReadOnly/competences-read-only.tpl.html',\n scope: {\n trainee: \"=\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('courseReadOnly', courseReadOnly);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name courseReadOnly\r\n * @restrict E\r\n * @description\r\n * Initialize read only view of what was submitted\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function courseReadOnly() {\n function link(scope) {\n scope.leftScroll = leftScroll;\n scope.rightScroll = rightScroll;\n scope.selectedTraineeSession = selectedTraineeSession;\n scope.selected = false;\n scope.selectedAbsentTraineeSession = selectedAbsentTraineeSession;\n scope.selectedPhase = scope.phases.find(function (x) {\n return x.PhaseId == scope.session.PhaseId;\n });\n scope.selectedTraineeBadge = {\n crewId: scope.session.TraineesSessions[0].CrewId\n };\n\n function leftScroll() {\n document.querySelector('.horizontal-scroll').scrollLeft -= 500;\n }\n\n function rightScroll() {\n document.querySelector('.horizontal-scroll').scrollLeft += 500;\n }\n\n function selectedTraineeSession() {\n return function (traineeSession) {\n var showSession = false;\n\n if (traineeSession.CrewId === scope.selectedTraineeBadge.crewId) {\n showSession = true;\n }\n\n return showSession;\n };\n }\n\n function selectedAbsentTraineeSession() {\n return function (traineeSession) {\n var showPanel = false;\n\n if (traineeSession.CrewId === scope.selectedTraineeBadge.crewId && traineeSession.Items.length == 0) {\n showPanel = true;\n }\n\n return showPanel;\n };\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: \"views/TrainingReadOnly/course-read-only.tpl.html\",\n scope: {\n phases: \"=\",\n session: \"=\"\n },\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('gradingReadOnly', gradingReadOnly);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name gradingReadOnly\r\n * @restrict E\r\n * @description\r\n * Implementation of grading read only\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function gradingReadOnly() {\n function link(scope, element, attrs) {\n if (scope.settings) {\n scope.grading.GradeType = scope.settings.GradeType;\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/TrainingReadOnly/grading-read-only.tpl.html',\n scope: {\n grading: \"=\",\n settings: \"=\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('sectorHistory', sectorHistory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name sectorHistory\r\n * @restrict E\r\n * @description\r\n * Implementation of sector history\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function sectorHistory() {\n function link(scope, element, attrs) {}\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/TrainingReadOnly/sector-history.tpl.html',\n scope: {\n history: \"=\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('syllabusProgressReadOnly', syllabusProgressReadOnly);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name syllabusReadOnly\r\n * @restrict E\r\n * @description\r\n * Initialize read only view of submitted syllabus\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function syllabusProgressReadOnly() {\n function link(scope) {\n scope.showRemarks = {\n value: false\n };\n scope.oneAtATime = true;\n scope.filterItems = filterItems;\n scope.toggleItems = toggleItems;\n setSyllabus(scope.history);\n\n function setSyllabus(history) {\n var traineeSessionItems = [];\n scope.phase.Syllabus.SyllabusItems.forEach(function (item) {\n var syllabusItem = JSON.parse(JSON.stringify(item));\n syllabusItem.Tries = [];\n syllabusItem.Selected = false;\n var relatedSessionItem = history.SyllabusProgress.find(function (x) {\n return x.SyllabusItemId == syllabusItem.Id;\n });\n\n if (relatedSessionItem) {\n syllabusItem.hasRemarks = relatedSessionItem.Tries.some(function (x) {\n return x.Comments && x.Comments.length > 0;\n }) || relatedSessionItem.Tries.some(function (t) {\n return t.TryGrading.Competences.some(function (x) {\n return x.Comments && x.Comments.length > 0;\n });\n });\n syllabusItem.Selected = true;\n syllabusItem.Tries = relatedSessionItem.Tries;\n syllabusItem.Tries.forEach(function (attempt) {\n attempt.Selected = true;\n });\n }\n\n setPanelStyle(syllabusItem);\n traineeSessionItems.push(syllabusItem);\n });\n history.ItemsGrouped = SyllabusGrouping(traineeSessionItems);\n }\n\n function setPanelStyle(item) {\n var historyTriesCount = item.Tries.filter(function (x) {\n return x.isReadOnly;\n }).length;\n var newTriesCount = item.Tries.filter(function (x) {\n return !x.isReadOnly && x.Selected;\n }).length;\n item.TriesPerformedCount = historyTriesCount + newTriesCount;\n var completedItem = item.TriesPerformedCount >= item.MandatoryCount;\n\n if (item.MandatoryCount == 0) {\n //non-mandatory items are considered completed if performed at least once\n completedItem = item.TriesPerformedCount >= 1;\n }\n\n if (completedItem) {\n item.PanelClass = 'panel-green panel-border-left-green ';\n } else {\n item.PanelClass = 'panel-border-left-blue ';\n }\n }\n\n function SyllabusGrouping(items) {\n //Syllabus Items Group By 'GroupId'\n var syllabusGroups = [];\n items.forEach(function (item) {\n if (!syllabusGroups.some(function (x) {\n return x.Id == item.SelectedGroup.Id;\n })) {\n if (!item.SelectedGroup) {\n item.SelectedGroup = {\n Id: 0,\n Title: 'General'\n };\n }\n\n var syllabusGroup = {\n Id: item.SelectedGroup.Id,\n Title: item.SelectedGroup.Title ? item.SelectedGroup.Title : 'General',\n Items: []\n };\n syllabusGroup.Items.push(item);\n syllabusGroups.push(syllabusGroup);\n } else {\n syllabusGroups.filter(function (x) {\n return x.Id == item.SelectedGroup.Id;\n })[0].Items.push(item);\n }\n });\n return syllabusGroups;\n }\n\n function filterItems() {\n return function (item) {\n var showItem = true;\n\n if (scope.showRemarks.value) {\n showItem = item.hasRemarks;\n } else {\n scope.oneAtATime = true;\n }\n\n return showItem;\n };\n }\n\n function toggleItems() {\n scope.oneAtATime = !scope.showRemarks.value;\n scope.history.ItemsGrouped.forEach(function (syllabusGroup) {\n syllabusGroup.Items.forEach(function (item) {\n item.isOpen = scope.showRemarks.value;\n });\n });\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: 'views/TrainingReadOnly/syllabus-progress-read-only.tpl.html',\n scope: {\n phase: \"=\",\n history: \"=\"\n },\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('syllabusReadOnly', syllabusReadOnly);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name syllabusReadOnly\r\n * @restrict E\r\n * @description\r\n * Initialize read only view of submitted syllabus\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function syllabusReadOnly() {\n function link(scope) {\n setSyllabus(scope.traineeSession);\n\n function setSyllabus(traineeSession) {\n var traineeSessionItems = [];\n scope.phase.Syllabus.SyllabusItems.forEach(function (item) {\n var syllabusItem = JSON.parse(JSON.stringify(item));\n syllabusItem.Tries = [];\n syllabusItem.Selected = false;\n var relatedSessionItem = null;\n\n if (scope.type == \"signature\") {\n relatedSessionItem = traineeSession.Items.find(function (x) {\n return x.Id == syllabusItem.Id;\n });\n } else {\n relatedSessionItem = traineeSession.Items.find(function (x) {\n return x.SyllabusItemId == syllabusItem.Id;\n });\n }\n\n if (relatedSessionItem) {\n syllabusItem.Selected = true;\n syllabusItem.Tries = relatedSessionItem.Tries;\n }\n\n if (scope.type == \"signature\") {\n setPanelStyleByProgress(syllabusItem);\n } else {\n setPanelStyleBySelected(syllabusItem);\n }\n\n traineeSessionItems.push(syllabusItem);\n });\n traineeSession.ItemsGrouped = SyllabusGrouping(traineeSessionItems);\n traineeSession.ItemsGrouped.forEach(function (group) {\n group.Items.forEach(function (item) {\n //find first not ReadOnly try\n item.firstTry = item.Tries.find(function (x) {\n return !x.isReadOnly;\n });\n });\n });\n }\n\n function setPanelStyleByProgress(item) {\n var historyTriesCount = item.Tries.filter(function (x) {\n return x.isReadOnly;\n }).length;\n var newTriesCount = item.Tries.filter(function (x) {\n return !x.isReadOnly && x.Selected;\n }).length;\n item.TriesPerformedCount = historyTriesCount + newTriesCount;\n var completedItem = item.TriesPerformedCount >= item.MandatoryCount;\n\n if (item.MandatoryCount == 0) {\n //non-mandatory items are considered completed if performed at least once\n completedItem = item.TriesPerformedCount >= 1;\n }\n\n var nonCompetentItem = false;\n\n if (item.IsGradable && item.Selected) {\n var gradingType = item.GradeType; //Numeric or Outcome or Competences\n\n var traineeSelectedTries = item.Tries.filter(function (x) {\n return x.Selected;\n });\n traineeSelectedTries.forEach(function (selectedTry) {\n if (!invalidItem && gradingType == \"Outcome\" && selectedTry.TryGrading.Grade == \"Fail\") {\n nonCompetentItem = true;\n }\n });\n }\n\n if (completedItem && !nonCompetentItem) {\n item.PanelClass = 'panel-green panel-border-left-green ';\n } else if (completedItem && nonCompetentItem) {\n item.PanelClass = 'panel-border-left-pink';\n } else {\n item.PanelClass = 'panel-border-left-blue ';\n }\n }\n\n function setPanelStyleBySelected(item) {\n var newTriesCount = item.Tries.filter(function (x) {\n return x.Selected;\n }).length;\n var selectedItem = newTriesCount > 0;\n var nonCompetentItem = false;\n var completedItem = item.Tries.length >= item.MandatoryCount;\n\n if (item.MandatoryCount == 0) {\n //non-mandatory items are considered completed if performed at least once\n completedItem = item.TriesPerformedCount >= 1;\n }\n\n if (item.IsGradable && item.Selected) {\n var outcomeType = item.GradeType == \"Outcome\";\n var traineeSelectedTries = item.Tries.filter(function (x) {\n return x.Selected;\n });\n\n if (outcomeType) {\n traineeSelectedTries.forEach(function (selectedTry) {\n if (outcomeType && selectedTry.TryGrading.Grade == \"Fail\") {\n nonCompetentItem = true;\n }\n });\n }\n }\n\n if (completedItem && selectedItem && !nonCompetentItem) {\n item.PanelClass = 'panel-green panel-border-left-green ';\n } else if (completedItem && selectedItem && nonCompetentItem) {\n item.PanelClass = 'panel-border-left-pink';\n } else {\n item.PanelClass = 'panel-border-left-blue ';\n }\n }\n\n function SyllabusGrouping(items) {\n //Syllabus Items Group By 'GroupId'\n var syllabusGroups = [];\n items.forEach(function (item) {\n if (!syllabusGroups.some(function (x) {\n return x.Id == item.SelectedGroup.Id;\n })) {\n if (!item.SelectedGroup) {\n item.SelectedGroup = {\n Id: 0,\n Title: 'General'\n };\n }\n\n var syllabusGroup = {\n Id: item.SelectedGroup.Id,\n Title: item.SelectedGroup.Title ? item.SelectedGroup.Title : 'General',\n Items: []\n };\n syllabusGroup.Items.push(item);\n syllabusGroups.push(syllabusGroup);\n } else {\n syllabusGroups.filter(function (x) {\n return x.Id == item.SelectedGroup.Id;\n })[0].Items.push(item);\n }\n });\n return syllabusGroups;\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: 'views/TrainingReadOnly/syllabus-read-only.tpl.html',\n scope: {\n phase: \"=\",\n traineeSession: \"=\",\n type: \"=\"\n },\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('additionalTraining', additionalTraining);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name additionalTraining\r\n * @restrict E\r\n * @description\r\n * Implementation of additional Training\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function additionalTraining($uibModal) {\n function link(scope) {\n scope.filterTrainee = filterTrainee;\n scope.yesAdditional = yesAdditional;\n scope.noAdditional = noAdditional;\n scope.NeedsAdditionalTraining = false;\n scope.clearAdditionalNotes = clearAdditionalNotes;\n scope.remarksSelection = remarksSelection;\n scope.completeAdditional = completeAdditional;\n scope.continueAdditional = continueAdditional;\n scope.selectedTrainee.startAdditional = false;\n scope.initializeAdditional = initializeAdditional;\n scope.toggleAdditional = toggleAdditional;\n scope.selectedTrainee.continueAdditional = false;\n scope.openAdditionalModal = openAdditionalModal;\n\n function yesAdditional(trainee) {\n scope.selectedTrainee.NeedsAdditionalTraining = true;\n trainee.Session.NeedsAdditionalTraining = true;\n scope.CompleteAdditionalTraining = false;\n trainee.Session.CompleteAdditionalTraining = false;\n trainee.Session.UnderAdditionalTraining = false;\n scope.selectedTrainee.startAdditional = true;\n remarksSelection(trainee);\n }\n\n function noAdditional(trainee) {\n scope.selectedTrainee.NeedsAdditionalTraining = false;\n trainee.Session.NeedsAdditionalTraining = false;\n scope.CompleteAdditionalTraining = false;\n trainee.Session.CompleteAdditionalTraining = false;\n trainee.Session.UnderAdditionalTraining = false;\n trainee.Session.AdditionalTrainingStatus = 'None';\n clearAdditionalNotes(trainee);\n }\n\n function clearAdditionalNotes(trainee) {\n scope.selectedTrainee.Session.AdditionalTrainingRemarks = '';\n trainee.Session.AdditionalTrainingRemarks = '';\n }\n\n function completeAdditional(trainee) {\n scope.selectedTrainee.NeedsAdditionalTraining = false;\n trainee.Session.NeedsAdditionalTraining = false;\n scope.CompleteAdditionalTraining = true;\n trainee.Session.CompleteAdditionalTraining = true;\n trainee.Session.UnderAdditionalTraining = true;\n remarksSelection(trainee);\n }\n\n function continueAdditional(trainee) {\n scope.selectedTrainee.NeedsAdditionalTraining = true;\n trainee.Session.NeedsAdditionalTraining = true;\n scope.CompleteAdditionalTraining = false;\n trainee.Session.CompleteAdditionalTraining = false;\n trainee.Session.UnderAdditionalTraining = true;\n remarksSelection(trainee);\n }\n\n function filterTrainee() {\n return function (trainee) {\n var showTrainee = true;\n\n if (scope.selectedTrainee) {\n //individual grading view: filter selected\n showTrainee = scope.selectedTrainee.CrewId == trainee.CrewId;\n }\n\n return showTrainee;\n };\n }\n\n function remarksSelection(trainee) {\n trainee.Session.AdditionalTrainingRemarks = scope.selectedTrainee.Session.AdditionalTrainingRemarks;\n }\n\n function toggleAdditional(trainee) {\n if (scope.selectedTrainee.continueAdditional) {\n continueAdditional(trainee);\n } else {\n completeAdditional(trainee);\n }\n }\n\n function initializeAdditional(trainee) {\n if (scope.selectedTrainee.startAdditional) {\n yesAdditional(trainee);\n } else {\n noAdditional(trainee);\n }\n }\n\n function openAdditionalModal(userInput) {\n $uibModal.open({\n templateUrl: 'views/Dialogs/dlgAdditionalTraining.html',\n controller: 'AdditionalTrainingModalCtrl',\n size: 'md',\n backdrop: 'static',\n keyboard: false,\n resolve: {\n retVal: function retVal() {\n return userInput;\n },\n startAdd: userInput\n }\n });\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: 'views/Training/additionalTraining.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('AdditionalTrainingModalCtrl', AdditionalTrainingModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name AdditionalTrainingModalCtrl\r\n * @description \r\n * Manages Additional Training Modal\r\n * @ngInject\r\n */\n\n function AdditionalTrainingModalCtrl($scope, $uibModalInstance, retVal) {\n $scope.ok = ok;\n $scope.cancel = cancel;\n\n if (retVal) {\n $scope.startAdd = true;\n } else {\n $scope.startAdd = false;\n }\n /**\r\n * Close modal after confirm\r\n * @memberof AdditionalTrainingModalCtrl\r\n */\n\n\n function ok() {\n $uibModalInstance.close(null);\n }\n /**\r\n * Close Modal\r\n * @memberof AdditionalTrainingModalCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('certificateExam', certificateExam);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name certificateExam\r\n * @restrict E\r\n * @description\r\n * Implementation of certificate exam grading\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function certificateExam(TrainingSessionFactory, FlightSessionFactory) {\n function link(scope, element, attrs) {\n if (scope.trainees) collapseAll();\n scope.validateTrainee = validateTrainee;\n scope.getRemainingCharacters = getRemainingCharacters;\n scope.collapseAll = collapseAll;\n scope.gradeUp = gradeUp;\n scope.gradeDown = gradeDown;\n var courseId = scope.dutyCourse.Id;\n var isGround = false;\n\n if (scope.groundDuty) {\n isGround = true;\n var date = scope.groundDuty.DutyDateS;\n var dutyId = scope.groundDuty.Id;\n } else {\n var date = scope.crewRouteDuty.date;\n var dutyNo = scope.crewRouteDuty.DutyNo;\n var dutyDay = scope.crewRouteDuty.DutyDay;\n }\n\n var gradeBase = scope.selectedPhase.ReleaseGrading.CertificateGradeBase;\n scope.gradeBase = gradeBase;\n scope.gradeMin = 0;\n scope.gradeMax = 100; //Accordion setting\n\n scope.oneAtATime = true;\n scope.gradingStatus = 'All'; //Initialize trainees \n\n scope.sessions = [];\n scope.trainees.filter(function (x) {\n return x.EligibilityStatus && !x.Session.Absent;\n }).forEach(function (trainee) {\n var session = trainee.Session.ReleaseGrading;\n session.Name = trainee.Name;\n session.AimsId = trainee.AimsId;\n session.isOpen = false;\n if (!session.CertificateOutcome) session.CertificateOutcome = \"Pass\";\n if (gradeBase && !session.Grade) session.Grade = gradeBase;\n if (!gradeBase) session.Grade = null;\n scope.sessions.push(session);\n });\n scope.sessions.forEach(function (traineeSession) {\n validateGrading(traineeSession);\n });\n\n function validateGrading(trainee) {\n // Invalid grading\n // 1. If none\n // 2. Over gradeMax\n // 3. Below gradeMin\n // 4. Non numeric\n trainee.isCertificateValid = gradeBase ? trainee.Grade != null && trainee.Grade != undefined : true;\n }\n\n function validateTrainee(trainee) {\n if (gradeBase) {\n validateGrading(trainee);\n\n if (trainee.isCertificateValid) {\n calculateOutcome(trainee);\n }\n }\n\n if (isGround) {\n TrainingSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyId, console.log, function (e) {\n console.log(e);\n });\n } else {\n FlightSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyNo, dutyDay, console.log, function (e) {\n console.log(e);\n });\n }\n }\n\n function gradeUp(trainee) {\n if (trainee.isCertificateValid && trainee.Grade < scope.gradeMax) {\n trainee.Grade++;\n }\n\n if (!trainee.isCertificateValid) {\n trainee.Grade++;\n }\n\n validateTrainee(trainee);\n }\n\n function gradeDown(trainee) {\n if (trainee.isExamValid && trainee.Grade > scope.gradeMin) {\n trainee.Grade--;\n }\n\n if (!trainee.isExamValid) {\n trainee.Grade--;\n }\n\n validateTrainee(trainee);\n }\n\n function calculateOutcome(trainee) {\n if (trainee.Grade < gradeBase) {\n trainee.CertificateOutcome = \"Fail\";\n } else {\n trainee.CertificateOutcome = \"Pass\";\n }\n }\n\n function getRemainingCharacters(text, max) {\n if (typeof text === \"undefined\" || text === null) return '';\n if (typeof max === \"undefined\" || max === null || max < 0 || !max) max = 4000;\n var length = text.length;\n return 'characters left: ' + (max - length);\n }\n\n function collapseAll() {\n scope.isAllOpen = !scope.isAllOpen;\n scope.trainees.forEach(function (trainee) {\n var session = trainee.Session.ReleaseGrading;\n session.isOpen = scope.isAllOpen;\n });\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/Training/certificate-exam.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('CompetenceModalCtrl', CompetenceModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CompetenceModalCtrl\r\n * @description \r\n * Show competence grading helper\r\n * @ngInject\r\n */\n\n function CompetenceModalCtrl($scope, $uibModalInstance, competence) {\n $scope.close = close;\n $scope.competence = competence;\n /**\r\n * Close the modal\r\n * @memberof CompetenceModalCtrl\r\n */\n\n function close() {\n $uibModalInstance.close($scope.competence.Grading);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('competences', competences);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name certificates\r\n * @restrict E\r\n * @description\r\n * Implementation of competences\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function competences($uibModal, $timeout) {\n function link(scope, element, attrs) {\n scope.manageCompetenceGrading = manageCompetenceGrading;\n scope.selectSubCompetence = selectSubCompetence;\n scope.openGradingModal = openGradingModal;\n scope.trainee.Competences.forEach(function (competence) {\n competence.isCollapsed = competence.hasMandatory || competence.hasOptional;\n competence.showComments = competence.hasMandatory || competence.hasOptional || competence.Comments && competence.Comments != \"\";\n });\n validateTraineeCompetences(scope.trainee);\n\n function validateTraineeCompetences(trainee) {\n var missingGrading = trainee.Competences.some(function (c) {\n return c.Grading == null;\n });\n var missingPerformanceIndicators = trainee.Competences.filter(function (c) {\n return c.hasMandatory;\n }).some(function (c) {\n return !c.SubCompetences.some(function (sub) {\n return sub.Selected;\n });\n });\n trainee.isCompetenceValid = !missingGrading && !missingPerformanceIndicators;\n }\n\n function manageCompetenceGrading(competence) {\n var grading = competence.Grading ? Number(competence.Grading) : null;\n var hadMandatory = competence.hasMandatory;\n var hadOptional = competence.hasOptional;\n competence.hasMandatory = competence.MandatorySub.includes(grading);\n competence.hasOptional = competence.OptionalSub.includes(grading);\n competence.isCollapsed = competence.hasMandatory || competence.hasOptional;\n if (competence.isCollapsed) competence.showComments = true; //From Mandatory to None remove selected Sub Competences\n\n if ((hadMandatory || hadOptional) && !competence.hasMandatory && !competence.hasOptional) {\n competence.SubCompetences.forEach(function (sub) {\n sub.Selected = false;\n });\n }\n\n validateTraineeCompetences(scope.trainee);\n\n switch (competence.Grading) {\n case 5:\n competence.GradingMessage = competence.GradeA;\n break;\n\n case 4:\n competence.GradingMessage = competence.GradeB;\n break;\n\n case 3:\n competence.GradingMessage = competence.GradeC;\n break;\n\n case 2:\n competence.GradingMessage = competence.GradeD;\n break;\n\n case 1:\n competence.GradingMessage = competence.GradeE;\n break;\n\n default:\n competence.GradingMessage = \"\";\n }\n\n scope.gradingSelection();\n }\n\n function selectSubCompetence(sub) {\n sub.Selected = !sub.Selected;\n if (sub.Selected) scope.gradingSelection();\n validateTraineeCompetences(scope.trainee);\n }\n\n function openGradingModal(_competence) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgCompetenceGrading.html',\n controller: 'CompetenceModalCtrl',\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n competence: function competence() {\n return _competence;\n }\n }\n });\n modalInstance.result.then(function (grading) {\n if (grading) {\n manageCompetenceGrading(_competence, grading);\n }\n });\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/Training/competences.tpl.html',\n scope: {\n trainee: \"=\",\n gradingSelection: \"&onGradingSelection\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('courseFooter', courseFooter);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name courseFooter\r\n * @restrict E\r\n * @description\r\n * Implementation of courseFooter (appears in course view)\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */\n\n function courseFooter($location, $routeParams) {\n function link(scope) {\n scope.gotoCalendar = gotoCalendar;\n scope.gotoGroundDuty = gotoGroundDuty;\n scope.gotoCrewRoute = gotoCrewRoute;\n scope.gotoFlight = gotoFlight;\n\n function gotoCalendar() {\n $location.path(\"/\");\n }\n\n function gotoGroundDuty() {\n $location.path('/groundDuty/' + Number($routeParams.dutyId));\n }\n\n function gotoCrewRoute() {\n var dutyNo = scope.crewRouteDuty.DutyNo;\n var dutyDay = scope.crewRouteDuty.DutyDay;\n $location.path('/crewRoute/' + dutyNo + '/' + dutyDay);\n }\n\n function gotoFlight() {\n var flightId = Number($routeParams.flightId);\n $location.path('/flightinfo/' + flightId);\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: \"views/Training/course-footer.tpl.html\",\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('course', course);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name course\r\n * @restrict E\r\n * @description\r\n * Implementation of training course\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function course(GroundDutyFactory, CourseFactory, TrainingSessionFactory, FlightSessionFactory, $timeout, $uibModal, $location, $routeParams, $window) {\n function link(scope) {\n var _courseId = scope.dutyCourse.Id;\n var isGround = false;\n\n if (scope.groundDuty) {\n isGround = true;\n var _date = scope.groundDuty.DutyDateS;\n var _dutyId = scope.groundDuty.Id;\n } else {\n var _date = scope.crewRouteDuty.date;\n var _dutyNo = scope.crewRouteDuty.DutyNo;\n var _dutyDay = scope.crewRouteDuty.DutyDay;\n var trainingFlightIds = scope.crewRouteDuty.Courses.find(function (x) {\n return x.CourseId == _courseId && new moment(x.Date).isSame(_date);\n }).TrainingFlightIds;\n if (scope.course.Media) scope.course.Media.radioModel = \"Flight\";\n }\n\n scope.isGround = isGround;\n scope.updateSession = updateSession;\n scope.availableCourseInfo = false;\n scope.oneTraineeAtATime = true;\n scope.allAbsent = false;\n scope.SubmitSession = SubmitSession;\n scope.close = close;\n scope.updateTraineeSignatures = updateTraineeSignatures;\n scope.checkReleaseAvailability = checkReleaseAvailability;\n scope.setReleaseStatus = setReleaseStatus;\n scope.reloadReleasePanel = reloadReleasePanel;\n scope.showReleasePanel = showReleasePanel;\n scope.filterSelectedSyllabus = filterSelectedSyllabus;\n scope.filterPresentTrainees = filterPresentTrainees;\n scope.selectedPhaseIndex = selectedPhaseIndex();\n scope.releaseTrainee = releaseTrainee;\n scope.showReleaseBtn = showReleaseBtn;\n scope.showGroupReleaseBtn = showGroupReleaseBtn;\n scope.releaseGroup = releaseGroup;\n scope.validateTraineeForm = validateTraineeForm;\n scope.openTraineeSignature = openTraineeSignature;\n scope.resetSignature = resetSignature;\n scope.getTraineeClass = getTraineeClass;\n scope.leftScroll = leftScroll;\n scope.rightScroll = rightScroll;\n scope.togglePanel = togglePanel;\n scope.isReleaseSelected = false;\n scope.toggleBtn = toggleBtn;\n scope.setAdditionalTrainingDetails = setAdditionalTrainingDetails;\n scope.hasLowDayGrading = hasLowDayGrading;\n scope.hasLowSyllabusGrading = hasLowSyllabusGrading;\n\n if (scope.selectedPhase.ModuleType == \"Training\" && scope.selectedPhase.EnableAdditionalTraining) {\n scope.AvailableAdditionalTraining = true;\n }\n\n function setAdditionalTrainingDetails() {\n if (scope.isReleaseSelected) {\n if (scope.selectedTrainee.Session.AdditionalTrainingRemarks != undefined) {\n scope.selectedTrainee.Session.AdditionalTrainingRemarks = '';\n }\n\n scope.selectedTrainee.Session.CompleteAdditionalTraining = true;\n scope.selectedTrainee.Session.NeedsAdditionalTraining = false;\n }\n }\n\n function toggleBtn() {\n scope.isReleaseSelected = !scope.isReleaseSelected;\n }\n\n function selectedPhaseIndex() {\n var index = 0;\n scope.course.CrewCoursePhases.some(function (phase, i) {\n if (phase.PhaseId == scope.selectedPhase.PhaseId) {\n index = i;\n return true;\n }\n });\n return index;\n }\n\n function filterSelectedSyllabus() {\n return function (syllabus) {\n var showTrainee = true;\n\n if (scope.traineeSyllabi && scope.traineeSyllabi.length > 1) {\n showTrainee = syllabus.TraineeIds[0] == scope.selectedTrainee.CrewId;\n }\n\n return showTrainee;\n };\n }\n\n function filterPresentTrainees() {\n return function (trainee) {\n return !trainee.Session.Absent;\n };\n }\n\n scope.reloadFooter = true;\n scope.reloadRelease = true;\n setTraineeSessions();\n updateSession();\n setReleaseStatus();\n\n function ResetTraineeSignatures() {\n scope.trainees.forEach(function (trainee) {\n trainee.Session.Authorized = false;\n });\n }\n\n function setReleaseStatus() {\n scope.trainees.forEach(function (trainee) {\n trainee.ShowReleaseWarning = false;\n });\n scope.course.AvailableRelease = checkReleaseAvailability(); //Handle trainee signatures\n\n scope.requiresTraineeSignature = RequiresTraineeSignature();\n if (!scope.requiresTraineeSignature) ResetTraineeSignatures();\n scope.allSignaturesComplete = !scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.Session.Authorized;\n });\n scope.someSignaturesComplete = scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return x.Session.Authorized;\n }); //For flights : check minDays - minSectors\n\n if (!isGround && scope.course.AvailableRelease && (scope.selectedPhase.MinDays > 0 || scope.selectedPhase.MinSectors > 0)) {\n scope.trainees.filter(function (x) {\n return x.AvailableRelease;\n }).forEach(function (trainee) {\n var phaseInfo = trainee.Phases.find(function (x) {\n return x.PhaseId == scope.selectedPhase.PhaseId;\n });\n var completedDays = 0;\n var completedSectors = 0;\n\n if (phaseInfo.Sessions) {\n //previous sessions\n completedDays = phaseInfo.Sessions.length;\n phaseInfo.Sessions.forEach(function (pastSession) {\n if (pastSession.Sectors) {\n completedSectors = completedSectors + pastSession.Sectors.length;\n }\n });\n }\n\n trainee.CompletedDays = completedDays + 1; //add current day\n\n trainee.CompletedSectors = completedSectors + trainingFlightIds.length; //add current sectors\n\n if (trainee.CompletedDays < scope.selectedPhase.MinDays || trainee.CompletedSectors < scope.selectedPhase.MinSectors) {\n trainee.ShowReleaseWarning = true;\n }\n });\n } //For ground: check aircraft visits\n\n\n if (isGround && (scope.course.AvailableRelease || scope.selectedPhase.ModuleType == \"Check\") && scope.selectedPhase.AircraftTypes.length) {\n var trainees = scope.trainees;\n if (scope.selectedPhase.ModuleType != \"Check\") trainees.filter(function (x) {\n return x.AvailableRelease;\n });\n trainees.forEach(function (trainee) {\n var phaseInfo = trainee.Phases.find(function (x) {\n return x.PhaseId == scope.selectedPhase.PhaseId;\n });\n var visitedAircrafts = [];\n\n if (phaseInfo.Sessions) {\n //previous sessions\n phaseInfo.Sessions.forEach(function (session) {\n visitedAircrafts = visitedAircrafts.concat(session.AircraftTypesVisited);\n });\n }\n\n if (scope.course.Media) {\n trainee.visitedAircrafts = visitedAircrafts.concat(scope.course.Media.inputAircrafts); //add current arvis\n }\n\n trainee.pendingAircrafts = [];\n trainee.pairPendingAircrafts = [];\n var pendingAircrafts = [];\n scope.selectedPhase.AircraftTypes.forEach(function (type) {\n var array = type.split(','); //if arvi requirement is not met\n\n if (trainee.visitedAircrafts && !array.some(function (x) {\n return trainee.visitedAircrafts.includes(x);\n })) {\n var pendingArviList = [];\n\n if (array.length > 1) {\n array.forEach(function (arvi) {\n pendingArviList.push(arvi);\n });\n } else {\n pendingArviList.push(array[0]);\n }\n\n pendingAircrafts.push(pendingArviList);\n }\n });\n trainee.pendingAircrafts = pendingAircrafts;\n trainee.ShowReleaseWarning = trainee.pendingAircrafts.length > 0;\n });\n }\n\n scope.showReleaseWarning = scope.trainees.some(function (x) {\n return x.ShowReleaseWarning;\n });\n }\n\n function reloadReleasePanel() {\n setReleaseStatus();\n scope.reloadRelease = false;\n $timeout(function () {\n scope.reloadRelease = true;\n }, 100);\n }\n\n function updateSession() {\n scope.trainees.forEach(function (trainee) {\n trainee.Session.selected = false;\n });\n\n if (scope.selectedTraineeBadge && scope.trainees.find(function (x) {\n return x.CrewId == scope.selectedTraineeBadge.CrewId;\n })) {\n scope.trainees.find(function (x) {\n return x.CrewId == scope.selectedTraineeBadge.CrewId;\n }).Session.selected = true;\n scope.selectedTrainee = scope.trainees.find(function (x) {\n return x.Session.selected;\n });\n }\n\n if (isGround) {\n TrainingSessionFactory.updateSession(scope.trainees, scope.course, _courseId, _date, _dutyId, console.log, function (e) {\n console.log(e);\n });\n } else {\n FlightSessionFactory.updateSession(scope.trainees, scope.course, _courseId, _date, _dutyNo, _dutyDay, console.log, function (e) {\n console.log(e);\n });\n }\n }\n\n function setTraineeSessions() {\n var phase = scope.selectedPhase; // Set Day Grading\n\n var dayCompetences = phase.DayGrading.Competences;\n dayCompetences.forEach(function (competence) {\n competence.MandatorySub = setSubCompetenceValues(competence.MandatorySubCompetences);\n competence.OptionalSub = setSubCompetenceValues(competence.OptionalSubCompetences); //Filter out from optional the ones common with mandatory\n\n competence.OptionalSub = competence.OptionalSub.filter(function (c) {\n return !competence.MandatorySub.includes(c);\n });\n });\n var dayGradingSessions = scope.trainees.map(function (x) {\n return x.Session.DayGrading;\n });\n dayGradingSessions.forEach(function (traineeSession) {\n traineeSession.Competences = setTraineeCompetences(dayCompetences, traineeSession);\n }); // Set Release Grading\n\n var releaseCompetences = phase.ReleaseGrading.Competences;\n releaseCompetences.forEach(function (competence) {\n competence.MandatorySub = setSubCompetenceValues(competence.MandatorySubCompetences);\n competence.OptionalSub = setSubCompetenceValues(competence.OptionalSubCompetences); //Filter out from optional the ones common with mandatory\n\n competence.OptionalSub = competence.OptionalSub.filter(function (c) {\n return !competence.MandatorySub.includes(c);\n });\n });\n var releaseGradingSessions = scope.trainees.map(function (x) {\n return x.Session.ReleaseGrading;\n });\n releaseGradingSessions.forEach(function (traineeSession) {\n traineeSession.Competences = setTraineeCompetences(releaseCompetences, traineeSession);\n }); // Set Syllabus\n\n if (scope.selectedPhase.Syllabus) setSyllabus(); //Check if all are absent\n\n if (scope.trainees && scope.trainees.length && !scope.trainees.some(function (x) {\n return !x.Session.Absent;\n })) {\n scope.allAbsent = true;\n }\n }\n\n function setSyllabus() {\n var traineeSyllabi = [];\n\n if (!scope.selectedPhase.Syllabus.IsGradable && !scope.selectedPhase.InFlight) {\n //Non Gradable syllabus & Ground: All trainees share the same syllabus\n var traineeSyllabus = {\n TraineeIds: scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).map(function (x) {\n return x.CrewId;\n }),\n Items: []\n };\n traineeSyllabi.push(traineeSyllabus);\n } else {\n //Gradable syllabus || flight: each trainee will have its own\n scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).forEach(function (trainee) {\n var traineeSyllabus = {\n TraineeIds: [trainee.CrewId],\n Items: []\n };\n traineeSyllabi.push(traineeSyllabus);\n });\n } //Set syllabus item sub competences \n\n\n scope.selectedPhase.Syllabus.SyllabusItems.forEach(function (item) {\n item.Competences.forEach(function (competence) {\n competence.MandatorySub = setSubCompetenceValues(competence.MandatorySubCompetences);\n competence.OptionalSub = setSubCompetenceValues(competence.OptionalSubCompetences); //Filter out from optional the ones common with mandatory\n\n competence.OptionalSub = competence.OptionalSub.filter(function (c) {\n return !competence.MandatorySub.includes(c);\n });\n });\n });\n scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).forEach(function (trainee) {\n var traineeSessionItems = [];\n scope.selectedPhase.Syllabus.SyllabusItems.forEach(function (item) {\n var syllabusItem = JSON.parse(JSON.stringify(item)); //Get any history tries\n\n var historyTries = [];\n\n if (syllabusItem.History && syllabusItem.History.length) {\n var itemsHistory = syllabusItem.History.filter(function (x) {\n return x.CrewId == trainee.CrewId;\n });\n\n if (itemsHistory.length) {\n var allHistoryTries = [];\n itemsHistory.forEach(function (item) {\n allHistoryTries = allHistoryTries.concat(item.Tries);\n });\n allHistoryTries.forEach(function (historyTry) {\n var performedTry = {\n ActionNo: historyTry.ActionNo,\n isReadOnly: true,\n Comments: historyTry.Comments,\n InstructorName: historyTry.InstructorName,\n SubmissionDate: historyTry.SubmissionDate,\n Grade: historyTry.TryGrading.Grade,\n AcTypes: historyTry.AcTypes,\n Sectors: historyTry.Sectors\n };\n historyTries.push(performedTry);\n });\n }\n }\n\n var relatedSessionItem = trainee.Session.Items.find(function (x) {\n return x.Id == syllabusItem.Id;\n }); //Pending tries\n\n var pendingTriesLeft = syllabusItem.MandatoryCount - historyTries.length;\n\n if (syllabusItem.MandatoryCount == 0 && historyTries.length == 0) {\n //for non-mandatory items: add 1 attempt if not already performed\n pendingTriesLeft = 1;\n }\n\n var pendingTries = [];\n\n for (var i = 0; i < pendingTriesLeft; i++) {\n pendingTries.push({\n Comments: null,\n ActionNo: historyTries.length + i + 1,\n isFirstTry: i == 0,\n TryGrading: {\n Grade: syllabusItem.DefaultGrade ? syllabusItem.DefaultGrade : null,\n Competences: [],\n GradeType: syllabusItem.GradeType\n }\n });\n } //Add pending tries to history tries\n\n\n var tries = historyTries.concat(pendingTries); //Create syllabus item depending on existing values\n\n if (!relatedSessionItem) {\n tries.filter(function (x) {\n return !x.isReadOnly;\n }).forEach(function (attempt) {\n attempt.TryGrading.Competences = setTraineeCompetences(syllabusItem.Competences, attempt.TryGrading);\n });\n var newItem = {\n RepeatRequired: false,\n Selected: false,\n Tries: tries,\n PhaseId: scope.selectedPhase.PhaseId,\n Id: syllabusItem.Id\n };\n traineeSessionItems.push(newItem);\n mergeSyllabusItemWithSession(syllabusItem, newItem);\n } else {\n var sessionTries = [];\n tries.forEach(function (tryItem) {\n var relatedSessionTry = relatedSessionItem.Tries.find(function (x) {\n return x.ActionNo == tryItem.ActionNo;\n });\n\n if (relatedSessionTry && !tryItem.isReadOnly) {\n sessionTries.push(deepCopy(relatedSessionTry));\n } else {\n sessionTries.push(deepCopy(tryItem));\n }\n }); //Add any Extra tries\n\n if (syllabusItem.MandatoryCount > 0) {\n var extraTries = relatedSessionItem.Tries.filter(function (x) {\n return x.ActionNo > syllabusItem.MandatoryCount && !x.isReadOnly;\n });\n sessionTries = sessionTries.concat(extraTries);\n }\n\n sessionTries.filter(function (x) {\n return !x.isReadOnly;\n }).forEach(function (attempt) {\n attempt.TryGrading.Competences = setTraineeCompetences(syllabusItem.Competences, attempt.TryGrading);\n });\n var existingItem = {\n RepeatRequired: relatedSessionItem.RepeatRequired,\n Selected: relatedSessionItem.Selected,\n Tries: sessionTries,\n PhaseId: scope.selectedPhase.PhaseId,\n Id: syllabusItem.Id\n };\n traineeSessionItems.push(existingItem);\n mergeSyllabusItemWithSession(syllabusItem, existingItem);\n }\n\n var traineeSyllabus = traineeSyllabi.find(function (x) {\n return x.TraineeIds.includes(trainee.CrewId);\n });\n\n if (!traineeSyllabus.Items.some(function (x) {\n return x.Id == syllabusItem.Id;\n })) {\n traineeSyllabus.Items.push(syllabusItem);\n }\n });\n trainee.Session.Items = traineeSessionItems;\n });\n traineeSyllabi.forEach(function (syllabus) {\n SyllabusGrouping(syllabus);\n });\n scope.traineeSyllabi = traineeSyllabi;\n }\n\n function mergeSyllabusItemWithSession(syllabusItem, sessionItem) {\n syllabusItem.RepeatRequired = sessionItem.RepeatRequired;\n syllabusItem.Selected = sessionItem.Selected;\n syllabusItem.Tries = sessionItem.Tries;\n }\n\n function leftScroll() {\n document.querySelector('.horizontal-scroll').scrollLeft -= 500;\n }\n\n function rightScroll() {\n document.querySelector('.horizontal-scroll').scrollLeft += 500;\n }\n\n function deepCopy(originalObject) {\n return JSON.parse(JSON.stringify(originalObject));\n }\n\n function SyllabusGrouping(syllabus) {\n //Syllabus Items Group By 'GroupId'\n var syllabusGroups = [];\n syllabus.Items.forEach(function (item) {\n if (!syllabusGroups.some(function (x) {\n return x.Id == item.SelectedGroup.Id;\n })) {\n if (!item.SelectedGroup) {\n item.SelectedGroup = {\n Id: 0,\n Title: 'General'\n };\n }\n\n var syllabusGroup = {\n Id: item.SelectedGroup.Id,\n Title: item.SelectedGroup.Title ? item.SelectedGroup.Title : 'General',\n Items: []\n };\n syllabusGroup.Items.push(item);\n syllabusGroups.push(syllabusGroup);\n } else {\n syllabusGroups.filter(function (x) {\n return x.Id == item.SelectedGroup.Id;\n })[0].Items.push(item);\n }\n });\n syllabus.ItemsGrouped = syllabusGroups;\n }\n\n function setTraineeCompetences(competences, sessionItem) {\n var traineeCompetences = [];\n competences.forEach(function (competence) {\n var traineeCompetence = JSON.parse(JSON.stringify(competence));\n var existingCompetence = sessionItem.Competences.find(function (x) {\n return x.Id == traineeCompetence.Id;\n }); //Get saved values\n\n traineeCompetence.Grading = existingCompetence ? existingCompetence.Grading : null;\n traineeCompetence.Comments = existingCompetence ? existingCompetence.Comments : null;\n\n if (existingCompetence) {\n traineeCompetence.SubCompetences.filter(function (x) {\n return existingCompetence.SubCompetences.some(function (y) {\n return y.Id == x.Id;\n });\n }).forEach(function (commonSub) {\n commonSub.Selected = existingCompetence.SubCompetences.find(function (s) {\n return s.Id == commonSub.Id;\n }).Selected;\n });\n traineeCompetence.hasMandatory = traineeCompetence.MandatorySub.includes(Number(traineeCompetence.Grading));\n traineeCompetence.hasOptional = traineeCompetence.OptionalSub.includes(Number(traineeCompetence.Grading));\n }\n\n traineeCompetences.push(traineeCompetence);\n });\n return traineeCompetences;\n }\n\n function setSubCompetenceValues(current) {\n var updated = [];\n var first = parseInt(current[0], 10);\n var last = current[current.length - 1];\n\n if (first) {\n for (var i = first; i <= last; i++) {\n updated.push(i);\n }\n }\n\n return updated;\n }\n /***************************************************************** Submit ********************************************************************************/\n\n\n function SubmitSession() {\n setReleaseStatus();\n\n if (!isValidForm()) {\n scope.modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgSubmitValidation.html',\n scope: scope,\n backdrop: 'static',\n keyboard: false,\n size: 'lg'\n });\n } else {\n if (isGround) {\n //Last save before submission\n TrainingSessionFactory.updateSession(scope.trainees, scope.course, _courseId, _date, _dutyId, function () {\n // Get all trainees found for this session (filter by course and date)\n TrainingSessionFactory.getSessionTrainees(_courseId, _date, _dutyId, function (Trainees) {\n manageSubmission(Trainees);\n });\n });\n } else {\n //Last save before submission\n FlightSessionFactory.updateSession(scope.trainees, scope.course, _courseId, _date, _dutyNo, _dutyDay, function () {\n // Get all trainees found for this session (filter by course and date)\n FlightSessionFactory.getSessionTrainees(_courseId, _date, _dutyNo, _dutyDay, function (Trainees) {\n manageSubmission(Trainees);\n });\n });\n }\n }\n }\n\n function manageSubmission(Trainees) {\n PrepareSessionForSubmission(Trainees);\n setReleaseStatus();\n\n var _requiresInstructorSignature = RequiresInstructorSignature();\n\n var _confirmationMsg = scope.selectedPhase.ReleaseGrading.ConfirmationMessage; // submit now\n\n var _releaseGrading = (scope.selectedPhase.ReleaseGrading.Comments || scope.selectedPhase.ReleaseGrading.GradeType == 'Numeric' || scope.selectedPhase.ReleaseGrading.GradeType == 'Outcome' || scope.selectedPhase.ReleaseGrading.Competences.length) && scope.selectedPhase.ReleaseGrading.GradeType != 'CertificateExam'; //var isAdditionalTraining = false; \n\n\n var _needsAdditionalTraining = false;\n\n if (scope.selectedTrainee != null) {\n _needsAdditionalTraining = scope.selectedTrainee.NeedsAdditionalTraining;\n }\n\n scope.modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgSign.html',\n controller: 'SignatureModalCtrl',\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n courseId: function courseId() {\n return _courseId;\n },\n date: function date() {\n return _date;\n },\n dutyId: function dutyId() {\n return _dutyId;\n },\n dutyNo: function dutyNo() {\n return _dutyNo;\n },\n dutyDay: function dutyDay() {\n return _dutyDay;\n },\n confirmationMsg: function confirmationMsg() {\n return _confirmationMsg;\n },\n requiresInstructorSignature: function requiresInstructorSignature() {\n return _requiresInstructorSignature;\n },\n trainees: function trainees() {\n return scope.trainees;\n },\n submitSession: function submitSession() {\n return SaveSession;\n },\n releaseGrading: function releaseGrading() {\n return _releaseGrading;\n },\n isReleased: function isReleased() {\n return scope.course.ReleasedPhase;\n },\n needsAdditionalTraining: function needsAdditionalTraining() {\n return _needsAdditionalTraining;\n }\n }\n });\n scope.modalInstance.result.then(function (result) {\n if (result.success) {\n $location.path(\"/\");\n }\n });\n }\n\n function RequiresTraineeSignature() {\n // End of session signature\n var endOfSessionSignature = scope.selectedPhase.DayGrading.TraineeSignature; // End of module signature\n\n var endOfModuleSignature = scope.course.ReleasedPhase && scope.selectedPhase.ReleaseGrading.TraineeSignature;\n return endOfSessionSignature || endOfModuleSignature;\n }\n\n function RequiresInstructorSignature() {\n /* Instructor signature needed if\r\n 1. Syllabus attached needs signature\r\n 2. Completed syllabus items need signature\r\n 3. End of session needs signature\r\n 4. Module is released and end of module needs signature\r\n */\n // 1. Check if syllabus exists and needs signature\n var syllabusSignature = scope.selectedPhase.Syllabus && scope.selectedPhase.Syllabus.SignatureRequired; // 2. Filter selected syllabus items & check if they need signature\n\n var selectedItems = [];\n scope.trainees.forEach(function (trainee) {\n var traineeSelectedItems = trainee.Session.Items.filter(function (x) {\n return x.Selected;\n }).map(function (x) {\n return x.Id;\n });\n selectedItems = selectedItems.concat(traineeSelectedItems);\n });\n selectedItems = _toConsumableArray(new Set(selectedItems));\n var syllabusItemSignature = scope.selectedPhase.Syllabus && scope.selectedPhase.Syllabus.SyllabusItems.filter(function (x) {\n return selectedItems.includes(x.Id);\n }).some(function (x) {\n return x.SignatureRequired;\n }); // 3. End of session signature\n\n var endOfSessionSignature = scope.selectedPhase.DayGrading.InstructorSignature; // 4. End of module signature\n\n var endOfModuleSignature = scope.course.AvailableRelease && scope.course.ReleasedPhase && scope.selectedPhase.ReleaseGrading.InstructorSignature;\n return syllabusSignature || syllabusItemSignature || endOfSessionSignature || endOfModuleSignature;\n }\n /**\r\n * Check if Release requirements are met\r\n * @param {object} group \r\n */\n\n\n function checkReleaseAvailability() {\n //Available Release if No pending mandatory items\n //Calculate item status for each trainee\n scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).forEach(function (sessionTrainee) {\n if (scope.selectedPhase.Syllabus) {\n var syllabusItems = scope.selectedPhase.Syllabus.SyllabusItems;\n sessionTrainee.Session.Items.forEach(function (sessionItem) {\n var performedTries = sessionItem.Tries.filter(function (x) {\n return x.isReadOnly || x.Selected;\n }).length; // history & current session\n\n var mandatoryCount = syllabusItems.find(function (x) {\n return x.Id == sessionItem.Id;\n }).MandatoryCount;\n sessionItem.Status = mandatoryCount > 0 && performedTries < mandatoryCount ? \"Pending\" : \"Completed\";\n });\n sessionTrainee.AvailableRelease = !sessionTrainee.Session.Items.some(function (x) {\n return x.Status == \"Pending\";\n });\n } else {\n sessionTrainee.AvailableRelease = true;\n }\n });\n\n if (scope.selectedPhase.ModuleType == \"Training\") {\n scope.trainees.filter(function (x) {\n return !x.Session.Absent && !x.AvailableRelease;\n }).forEach(function (trainee) {\n trainee.Session.Released = false;\n });\n\n if (scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.AvailableRelease;\n })) {\n scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).forEach(function (trainee) {\n trainee.Session.Released = false;\n });\n }\n }\n\n scope.course.ReleasedPhase = scope.trainees.filter(function (x) {\n return !x.Absent;\n }).some(function (x) {\n return x.Session.Released;\n });\n return !scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.AvailableRelease;\n });\n }\n\n function SaveSession(password, withRelease) {\n scope.submittedSession.SignaturePassword = password;\n\n if (scope.submittedSession.TraineeSessions.filter(function (x) {\n return x.AdditionalTrainingStatus == 'UnderAdditionalTraining';\n }).length > 0) {\n scope.submittedSession.TraineeSessions.filter(function (x) {\n return !x.Absent && scope.selectedTrainee.AdditionalTrainingStatus == 'UnderAdditionalTraining';\n }).forEach(function (trainee) {\n if (!trainee.NeedsAdditionalTraining) {\n trainee.NeedsAdditionalTraining = false;\n trainee.UnderAdditionalTraining = true;\n trainee.CompleteAdditionalTraining = true;\n }\n });\n }\n\n if (scope.submittedSession.TraineeSessions.find(function (x) {\n return x.CompleteAdditionalTraining == true;\n })) {\n scope.submittedSession.TraineeSessions.filter(function (x) {\n return !x.Absent && scope.selectedTrainee.AdditionalTrainingStatus == 'UnderAdditionalTraining';\n }).forEach(function (trainee) {\n if (!trainee.NeedsAdditionalTraining) {\n trainee.NeedsAdditionalTraining = false;\n trainee.UnderAdditionalTraining = true;\n trainee.CompleteAdditionalTraining = true;\n }\n });\n }\n\n if (withRelease) {\n scope.submittedSession.ReleasedPhase = true;\n scope.submittedSession.TraineeSessions.filter(function (x) {\n return !x.Absent;\n }).forEach(function (trainee) {\n trainee.Released = true;\n });\n }\n\n if (isGround) {\n return TrainingSessionFactory.submitSession(scope.submittedSession);\n } else {\n return FlightSessionFactory.submitSession(scope.submittedSession);\n }\n }\n\n function PrepareSessionForSubmission(Trainees) {\n // Filter Trainee Sessions\n var trainees = Trainees.filter(function (x) {\n return x.EligibilityStatus;\n });\n trainees.forEach(function (trainee) {\n trainee.Session.Items = trainee.Session.Items.filter(function (x) {\n return x.Selected;\n }); // Empty absent trainee sessions\n\n if (trainee.Session.Absent) {\n trainee.Session.Items = [];\n trainee.Session.DayGrading.Comments = null;\n trainee.Session.DayGrading.Competences = [];\n trainee.Session.DayGrading.Grade = null;\n trainee.Session.ReleaseGrading.Comments = null;\n trainee.Session.ReleaseGrading.Competences = [];\n trainee.Session.ReleaseGrading.Grade = null;\n trainee.Session.NeedsAdditionalTraining = false;\n trainee.Session.AdditionalTrainingRemarks = null;\n }\n });\n var sessionSectors = [];\n\n if (!isGround) {\n //Collect session sectors for flight\n trainingFlightIds.forEach(function (flightId) {\n var sector = {\n FlightId: flightId,\n PM: null,\n PF: null,\n SessionSectorSeats: []\n };\n sessionSectors.push(sector);\n });\n } // Create Session\n\n\n scope.submittedSession = {\n SessionDate: _date,\n CourseId: _courseId,\n GroundDutyIds: isGround ? [_dutyId] : [],\n Sectors: sessionSectors,\n AircraftVisits: scope.course.Media && scope.course.Media.radioModel == \"Aircraft\" ? scope.course.Media.inputAircrafts : [],\n SelectedMedia: scope.course.Media ? scope.course.Media.radioModel : \"\",\n SyntheticDeviceId: scope.course.Media && scope.course.Media.radioModel == \"Simulator\" ? scope.course.Media.selectedDevice.selection : null,\n ReleasedPhase: scope.course.ReleasedPhase,\n GradeType: scope.selectedPhase.DayGrading.GradeType,\n ReleaseGradeType: scope.selectedPhase.ReleaseGrading.GradeType,\n TraineeSessions: trainees.map(function (x) {\n return x.Session;\n }),\n SyllabusVersionId: scope.selectedPhase.Syllabus ? scope.selectedPhase.Syllabus.SyllabusVersionId : null,\n PhaseId: scope.selectedPhase.PhaseId,\n DowntimeDuration: scope.course.Media && scope.course.Media.radioModel == \"Simulator\" && scope.downtimeDuration.radioValue == 'true' ? scope.downtimeDuration.minutes : null\n };\n }\n\n function isValidForm() {\n /*Requirements before submitting a session\r\n 1. OnLine Mode\r\n 2. Date Allowed\r\n 3. Pending syllabus items\r\n 4. Pending syllabus items for different trainee\r\n 5. Media Validation\r\n 6. Day Grading\r\n 7. Release Grading\r\n 8. Certificate Exam Grading\r\n 9. Trainee Signature\r\n */\n var isValid = false;\n var info = {\n border: \"\",\n icon: \"\",\n msg: \"\",\n scrollToTop: false\n };\n\n if (!window.navigator.onLine) {\n info = {\n border: \"border-left-red\",\n icon: \"fa-warning text-red\",\n msg: \" Online mode is required in order to submit a training.

Check your connection and try again!

\",\n scrollToTop: false\n };\n } else if (!dateAllowed()) {\n info = {\n border: \"border-left-red\",\n icon: \"fa-calendar-times-o text-red\",\n msg: \"You can not submit a session earlier than its duty date!\",\n scrollToTop: false\n };\n } else if (scope.requiresTraineeSignature && !scope.allSignaturesComplete) {\n if (scope.selectedTrainee && !scope.selectedTrainee.Session.Authorized) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-pencil-square-o text-orange\",\n msg: \"\" + scope.selectedTrainee.Name + \" needs to sign the form!\",\n scrollToTop: false\n };\n } else {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"All trainees need to sign their forms!\",\n scrollToTop: true\n };\n }\n } else if (syllabusPending()) {\n var traineeDetailsMsg = \"\";\n\n if (scope.selectedTrainee && (scope.selectedPhase.Syllabus.IsGradable || scope.selectedPhase.InFlight)) {\n traineeDetailsMsg = \" for \" + scope.selectedTrainee.Name + \"\";\n }\n\n info = {\n border: \"border-left-orange\",\n icon: \"fa-calendar-times-o text-orange\",\n msg: \"Form cannot be submitted!

Please complete all mandatory syllabus items\" + traineeDetailsMsg + \"

\",\n scrollToTop: false\n };\n } else if (traineesPending()) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-calendar-times-o text-orange\",\n msg: \"Form cannot be submitted!

Please complete all trainee forms.

\",\n scrollToTop: true\n };\n } else if (!isMediaValid()) {\n if (scope.hasNoAircraft) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-plane text-orange\",\n msg: \"You need to provide an aircraft type!\",\n scrollToTop: true\n };\n } else if (scope.hasNoDevice) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-plane text-orange\",\n msg: \"You need to select a synthetic device!\",\n scrollToTop: true\n };\n }\n } else if (!isSyllabusGradingValid()) {\n var invalidTrainees = scope.trainees.filter(function (t) {\n return t.Session.SyllabusValidationErrors && t.Session.SyllabusValidationErrors.Items.length;\n });\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"Some of the selected syllabus items require a grading\",\n SyllabusErrors: invalidTrainees.map(function (t) {\n return t.Session.SyllabusValidationErrors;\n }),\n scrollToTop: false\n };\n } else if (!isGradingValid()) {\n if (!scope.gradingValidationInfo.isDayCompetencesValid || !scope.gradingValidationInfo.isReleaseCompetencesValid) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"You need to grade all competences before submitting!\",\n scrollToTop: false\n };\n } else if (!scope.gradingValidationInfo.isDayGradingValid || !scope.gradingValidationInfo.isReleaseGradingValid) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"You need to grade all trainees!\",\n scrollToTop: false\n };\n } else if (!scope.gradingValidationInfo.isCertificateGradingValid) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"You need to grade all certificate exams!\",\n scrollToTop: false\n };\n }\n } else {\n isValid = true;\n }\n\n scope.info = info;\n return isValid;\n }\n\n function dateAllowed() {\n var dateAllowed = false; //Submission is allowed only on the day of the training and after\n\n var trainingDay = moment.utc(_date).valueOf();\n var today = moment.utc().valueOf();\n\n if (today >= trainingDay) {\n dateAllowed = true;\n }\n\n return dateAllowed;\n }\n\n function syllabusPending() {\n var syllabus = scope.selectedPhase.Syllabus;\n var type = scope.selectedPhase.ModuleType;\n return syllabus && type == 'Check' && (scope.selectedTrainee && !scope.selectedTrainee.AvailableRelease || !scope.selectedTrainee && scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.AvailableRelease;\n }));\n }\n\n function traineesPending() {\n var syllabus = scope.selectedPhase.Syllabus;\n var type = scope.selectedPhase.ModuleType;\n return syllabus && type == 'Check' && scope.selectedTrainee && scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.AvailableRelease;\n });\n }\n\n function isSyllabusGradingValid() {\n var syllabus = scope.selectedPhase.Syllabus;\n\n if (syllabus && syllabus.IsGradable) {\n var gradableSyllabusItems = syllabus.SyllabusItems.filter(function (x) {\n return x.IsGradable;\n });\n var gradableSyllabusItemIds = gradableSyllabusItems.map(function (x) {\n return x.Id;\n }); //foreach trainee get selected tries that need grading\n\n scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).forEach(function (trainee) {\n var invalidItems = [];\n trainee.Session.Items.filter(function (x) {\n return x.Selected && gradableSyllabusItemIds.includes(x.Id);\n }).forEach(function (selectedItem) {\n var syllabusItem = gradableSyllabusItems.find(function (x) {\n return x.Id == selectedItem.Id;\n });\n var gradingType = syllabusItem.GradeType; //Numeric or Outcome or Competences\n\n var traineeSelectedTries = selectedItem.Tries.filter(function (x) {\n return x.Selected;\n });\n traineeSelectedTries.forEach(function (selectedTry) {\n var invalidGrading = gradingType != \"Competences\" && !selectedTry.TryGrading.Grade;\n var invalidCompetences = gradingType == \"Competences\" && !selectedTry.TryGrading.isCompetenceValid;\n\n if (invalidGrading || invalidCompetences) {\n invalidItems.push(syllabusItem.Title);\n }\n });\n });\n trainee.Session.SyllabusValidationErrors = {\n Name: trainee.Name,\n Items: invalidItems\n };\n });\n }\n\n return !scope.trainees.some(function (t) {\n return t.Session.SyllabusValidationErrors && t.Session.SyllabusValidationErrors.Items.length;\n });\n }\n\n function isGradingValid() {\n var isDayGradingValid = scope.selectedPhase.DayGrading.GradeType == \"NotSet\";\n var isReleaseGradingValid = scope.selectedPhase.ReleaseGrading.GradeType == \"NotSet\" || scope.selectedPhase.ReleaseGrading.GradeType == \"CertificateExam\" || !scope.course.AvailableRelease || !scope.course.ReleasedPhase;\n var isCertificateGradingValid = scope.selectedPhase.ReleaseGrading.GradeType != \"CertificateExam\" || !scope.course.ReleasedPhase;\n var isDayCompetencesValid = scope.selectedPhase.DayGrading.Competences.length == 0;\n var isReleaseCompetencesValid = scope.selectedPhase.ReleaseGrading.Competences.length == 0 || !scope.course.AvailableRelease || !scope.course.ReleasedPhase;\n if (!isDayGradingValid) isDayGradingValid = !scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.Session.DayGrading.isGradeValid;\n });\n if (!isReleaseGradingValid) isReleaseGradingValid = !scope.trainees.filter(function (x) {\n return !x.Session.Absent && x.Session.Released;\n }).some(function (x) {\n return !x.Session.ReleaseGrading.isGradeValid;\n });\n if (!isCertificateGradingValid) isCertificateGradingValid = !scope.trainees.filter(function (x) {\n return !x.Session.Absent && x.AvailableRelease;\n }).some(function (x) {\n return !x.Session.ReleaseGrading.isCertificateValid;\n });\n if (!isDayCompetencesValid) isDayCompetencesValid = !scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.Session.DayGrading.isCompetenceValid;\n });\n if (!isReleaseCompetencesValid) isReleaseCompetencesValid = !scope.trainees.filter(function (x) {\n return !x.Session.Absent && x.Session.Released;\n }).some(function (x) {\n return !x.Session.ReleaseGrading.isCompetenceValid;\n });\n scope.gradingValidationInfo = {\n isDayGradingValid: isDayGradingValid,\n isReleaseGradingValid: isReleaseGradingValid,\n isDayCompetencesValid: isDayCompetencesValid,\n isReleaseCompetencesValid: isReleaseCompetencesValid,\n isCertificateGradingValid: isCertificateGradingValid\n };\n return isDayGradingValid && isReleaseGradingValid && isDayCompetencesValid && isReleaseCompetencesValid && isCertificateGradingValid;\n }\n\n function isTraineeGradingValid(trainee) {\n var isDayGradingValid = scope.selectedPhase.DayGrading.GradeType == \"NotSet\";\n var isReleaseGradingValid = scope.selectedPhase.ReleaseGrading.GradeType == \"NotSet\" || scope.selectedPhase.ReleaseGrading.GradeType == \"CertificateExam\" || !scope.course.AvailableRelease || !scope.course.ReleasedPhase;\n var isCertificateGradingValid = scope.selectedPhase.ReleaseGrading.GradeType != \"CertificateExam\" || !scope.course.ReleasedPhase;\n var isDayCompetencesValid = scope.selectedPhase.DayGrading.Competences.length == 0;\n var isReleaseCompetencesValid = scope.selectedPhase.ReleaseGrading.Competences.length == 0 || !scope.course.AvailableRelease || !scope.course.ReleasedPhase;\n if (!isDayGradingValid) isDayGradingValid = trainee.Session.DayGrading.isGradeValid;\n if (!isReleaseGradingValid) isReleaseGradingValid = !trainee.Session.Released || trainee.Session.ReleaseGrading.isGradeValid;\n if (!isCertificateGradingValid) isCertificateGradingValid = !trainee.AvailableRelease || trainee.Session.ReleaseGrading.isCertificateValid;\n if (!isDayCompetencesValid) isDayCompetencesValid = trainee.Session.DayGrading.isCompetenceValid;\n if (!isReleaseCompetencesValid) isReleaseCompetencesValid = !trainee.Session.Released || trainee.Session.ReleaseGrading.isCompetenceValid;\n trainee.Session.gradingValidationInfo = {\n isDayGradingValid: isDayGradingValid,\n isReleaseGradingValid: isReleaseGradingValid,\n isDayCompetencesValid: isDayCompetencesValid,\n isReleaseCompetencesValid: isReleaseCompetencesValid,\n isCertificateGradingValid: isCertificateGradingValid\n };\n return isDayGradingValid && isReleaseGradingValid && isDayCompetencesValid && isReleaseCompetencesValid && isCertificateGradingValid;\n }\n\n function hasLowDayGrading(trainee) {\n scope.traineeHasLowGrading = false;\n var hasDayNumericGrading = scope.selectedPhase.DayGrading.GradeType == \"Numeric\";\n var hasDayOutcomeGrading = scope.selectedPhase.DayGrading.GradeType == \"Outcome\";\n var hasDayCompetences = scope.selectedPhase.DayGrading.Competences.length > 0;\n\n if (trainee != null) {\n if (hasDayNumericGrading && (trainee.Session.DayGrading.Grade == 1 || trainee.Session.DayGrading.Grade == 2)) {\n scope.traineeHasLowGrading = true;\n }\n\n if (hasDayOutcomeGrading && (trainee.Session.DayGrading.Grade == \"Fail\" || trainee.Session.DayGrading.Grade == \"PasswithTrainingRecommendation\")) {\n scope.traineeHasLowGrading = true;\n }\n\n if (hasDayCompetences) {\n trainee.Session.DayGrading.Competences.forEach(function (competence) {\n if (competence.hasMandatory) scope.traineeHasLowGrading = true;\n });\n }\n }\n\n return scope.traineeHasLowGrading;\n }\n\n function hasLowSyllabusGrading(trainee) {\n scope.traineeHasLowSyllabusGrading = false;\n var syllabus = scope.selectedPhase.Syllabus;\n\n if (trainee != null) {\n if (syllabus && syllabus.IsGradable) {\n var gradableSyllabusItems = syllabus.SyllabusItems.filter(function (x) {\n return x.IsGradable;\n });\n var gradableSyllabusItemIds = gradableSyllabusItems.map(function (x) {\n return x.Id;\n }); //get selected tries that has low grading\n\n trainee.Session.Items.filter(function (x) {\n return x.Selected && gradableSyllabusItemIds.includes(x.Id);\n }).forEach(function (selectedItem) {\n var traineeSelectedTries = selectedItem.Tries.filter(function (x) {\n return x.Selected;\n });\n traineeSelectedTries.forEach(function (selectedTry) {\n if (selectedTry.TryGrading.Grade == 1 || selectedTry.TryGrading.Grade == 2 || selectedTry.TryGrading.Grade == 'Fail') scope.traineeHasLowSyllabusGrading = true;\n\n if (selectedTry.TryGrading.GradeType == 'Competences') {\n selectedTry.TryGrading.Competences.forEach(function (competence) {\n if (competence.hasMandatory) scope.traineeHasLowSyllabusGrading = true;\n });\n }\n });\n });\n }\n }\n\n return scope.traineeHasLowSyllabusGrading;\n }\n\n function isMediaValid() {\n scope.hasNoAircraft = scope.course.Media && scope.course.Media.radioModel == \"Aircraft\" && !scope.course.Media.inputAircrafts.length;\n scope.hasNoDevice = scope.course.Media && scope.course.Media.radioModel == \"Simulator\" && !scope.course.Media.selectedDevice.selection;\n return !scope.hasNoAircraft && !scope.hasNoDevice;\n }\n /**\r\n * Triggered after a trainee has successfully signed\r\n */\n\n\n function updateTraineeSignatures() {\n updateSession();\n scope.allSignaturesComplete = !scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.Session.Authorized;\n });\n scope.someSignaturesComplete = scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return x.Session.Authorized;\n });\n }\n\n function close() {\n scope.modalInstance.close();\n\n if (scope.info && scope.info.scrollToTop) {\n $window.scrollTo(0, 0);\n }\n }\n\n function showReleasePanel(syllabus) {\n var retVal = false;\n var phase = scope.selectedPhase;\n var availableCourse = scope.availableCourse && scope.trainees.length;\n var isCheck = phase.ModuleType == 'Check';\n var releaseGrading = (phase.ReleaseGrading.Comments || phase.ReleaseGrading.GradeType == 'Numeric' || phase.ReleaseGrading.GradeType == 'Outcome' || phase.ReleaseGrading.Competences.length) && phase.ReleaseGrading.GradeType != 'CertificateExam';\n\n if (isCheck) {\n retVal = availableCourse && releaseGrading;\n } else if (scope.traineeSyllabi.length > 1) {\n var crewId = syllabus.TraineeIds[0];\n var trainee = scope.trainees.find(function (x) {\n return x.CrewId == crewId;\n });\n retVal = scope.reloadRelease && trainee.AvailableRelease && trainee.Session.Released && availableCourse && releaseGrading;\n } else {\n retVal = scope.reloadRelease && scope.course.AvailableRelease && scope.course.ReleasedPhase && availableCourse && releaseGrading;\n }\n\n return retVal;\n }\n\n function releaseTrainee(syllabus) {\n var crewIds = syllabus.TraineeIds;\n var trainees = scope.trainees.filter(function (x) {\n return crewIds.includes(x.CrewId);\n });\n trainees.forEach(function (trainee) {\n trainee.Session.Released = !trainee.Session.Released;\n });\n scope.course.ReleasedPhase = scope.trainees.filter(function (x) {\n return !x.Absent;\n }).some(function (x) {\n return x.Session.Released;\n });\n }\n\n function releaseGroup() {\n scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).forEach(function (trainee) {\n trainee.Session.Released = !trainee.Session.Released;\n });\n scope.course.ReleasedPhase = scope.trainees.filter(function (x) {\n return !x.Absent;\n }).some(function (x) {\n return x.Session.Released;\n });\n setReleaseStatus();\n }\n\n function showReleaseBtn(syllabus) {\n var retVal = false;\n var availableCourse = scope.availableCourse && scope.trainees.length;\n var isCheck = scope.selectedPhase.ModuleType == 'Check';\n\n if (isCheck) {\n retVal = false;\n } else if (scope.traineeSyllabi.length > 1) {\n var crewId = syllabus.TraineeIds[0];\n var trainee = scope.trainees.find(function (x) {\n return x.CrewId == crewId;\n });\n retVal = scope.reloadRelease && availableCourse && trainee.AvailableRelease && trainee.AdditionalTrainingStatus == 'UnderAdditionalTraining';\n } else {\n retVal = scope.reloadRelease && availableCourse && scope.course.AvailableRelease;\n }\n\n return retVal;\n }\n\n function showGroupReleaseBtn() {\n var retVal = false;\n var availableCourse = scope.availableCourse && scope.trainees.length > 0;\n var isCheck = scope.selectedPhase.ModuleType == 'Check';\n var releaseGrading = (scope.selectedPhase.ReleaseGrading.Comments || scope.selectedPhase.ReleaseGrading.GradeType == 'Numeric' || scope.selectedPhase.ReleaseGrading.GradeType == 'Outcome' || scope.selectedPhase.ReleaseGrading.Competences.length) && scope.selectedPhase.ReleaseGrading.GradeType != 'CertificateExam';\n\n if (isCheck) {\n retVal = false;\n } else {\n retVal = scope.reloadRelease && availableCourse && releaseGrading && !scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.AvailableRelease && x.AdditionalTrainingStatus != 'UnderAdditionalTraining';\n });\n }\n\n return retVal;\n }\n\n function getTraineeClass(crewId) {\n isSyllabusGradingValid();\n var textClass = \"\";\n var trainee = scope.trainees.find(function (x) {\n return x.CrewId == crewId;\n });\n var syllabus = scope.selectedPhase.Syllabus;\n var type = scope.selectedPhase.ModuleType;\n var allSyllabusCompleted = trainee.AvailableRelease; //Draft status\n\n var selectedItems = trainee.Session.Items.some(function (i) {\n return i.Tries.filter(function (t) {\n return !t.isReadOnly;\n }).some(function (t) {\n return t.Selected;\n });\n }); //Validate syllabus\n\n var validSyllabusGrading = !trainee.Session.SyllabusValidationErrors || !trainee.Session.SyllabusValidationErrors.Items.length; //Validate Day grading\n\n var isDayGradingValid = scope.selectedPhase.DayGrading.GradeType == \"NotSet\";\n var isDayCompetencesValid = scope.selectedPhase.DayGrading.Competences.length == 0;\n if (!isDayGradingValid) isDayGradingValid = trainee.Session.DayGrading.isGradeValid;\n if (!isDayCompetencesValid) isDayCompetencesValid = trainee.Session.DayGrading.isCompetenceValid; //Validate Release grading\n\n var isReleaseGradingValid = scope.selectedPhase.ReleaseGrading.GradeType == \"NotSet\" || scope.selectedPhase.ReleaseGrading.GradeType == \"CertificateExam\" || scope.selectedPhase.ModuleType == \"Training\" && (!trainee.AvailableRelease || !trainee.Session.Released);\n var isReleaseCompetencesValid = scope.selectedPhase.ReleaseGrading.Competences.length == 0 || scope.selectedPhase.ModuleType == \"Training\" && (!trainee.AvailableRelease || !trainee.Session.Released);\n if (!isReleaseGradingValid) isReleaseGradingValid = !trainee.Session.Released || trainee.Session.ReleaseGrading.isGradeValid;\n if (!isReleaseCompetencesValid) isReleaseCompetencesValid = !trainee.Session.Released || trainee.Session.ReleaseGrading.isCompetenceValid;\n\n if (selectedItems) {\n textClass = \"bg-amber text-white\";\n\n if (validSyllabusGrading && isDayGradingValid && isDayCompetencesValid && isReleaseGradingValid && isReleaseCompetencesValid && (type == 'Training' || allSyllabusCompleted)) {\n textClass = \"bg-green text-white\";\n }\n }\n\n return textClass;\n }\n\n function togglePanel(panelId) {\n $('#' + panelId).toggle();\n }\n /**\r\n * Toggle signature panel while trainee hasn't signed yet\r\n * @param {object} trainee \r\n */\n\n\n function openTraineeSignature(_trainee) {\n //Enter signature mode : trainee form becomes read-only\n if (!_trainee.Session.Authorized) {\n setReleaseStatus(); //Trainee can sign only if his form is valid\n\n if (!validateTraineeForm(_trainee)) {\n scope.modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgSubmitValidation.html',\n scope: scope,\n backdrop: 'static',\n keyboard: false,\n size: 'lg'\n });\n } else {\n scope.modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgTraineeSignature.html',\n controller: 'TraineeSignatureModalCtrl',\n scope: scope,\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n trainee: function trainee() {\n return _trainee;\n },\n signatureSuccess: function signatureSuccess() {\n return updateTraineeSignatures;\n }\n }\n });\n }\n }\n\n scope.someSignaturesComplete = scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return x.Session.Authorized;\n });\n }\n\n function validateTraineeForm(trainee) {\n var trainee = scope.selectedTrainee;\n var isValid = false;\n var info = {\n border: \"\",\n icon: \"\",\n msg: \"\",\n scrollToTop: false\n };\n\n if (!window.navigator.onLine) {\n info = {\n border: \"border-left-red\",\n icon: \"fa-warning text-red\",\n msg: \" Online mode is required in order to sign.

Check your connection and try again!

\",\n scrollToTop: false\n };\n } else if (syllabusPending()) {\n var traineeDetailsMsg = \"\";\n\n if (trainee && (scope.selectedPhase.Syllabus.IsGradable || scope.selectedPhase.InFlight)) {\n traineeDetailsMsg = \" for \" + trainee.Name + \"\";\n }\n\n info = {\n border: \"border-left-orange\",\n icon: \"fa-calendar-times-o text-orange\",\n msg: \"Form cannot be submitted!

Please complete all mandatory syllabus items\" + traineeDetailsMsg + \"

\",\n scrollToTop: false\n };\n } else if (!isSyllabusGradingValid() && trainee.Session.SyllabusValidationErrors && trainee.Session.SyllabusValidationErrors.Items.length) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"Some of the selected syllabus items require a grading\",\n SyllabusErrors: trainee.Session.SyllabusValidationErrors,\n scrollToTop: false\n };\n } else if (!isTraineeGradingValid(trainee)) {\n if (!trainee.Session.gradingValidationInfo.isDayCompetencesValid || !trainee.Session.gradingValidationInfo.isReleaseCompetencesValid) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"You need to grade all competences!\",\n scrollToTop: false\n };\n } else if (!trainee.Session.isDayGradingValid || !trainee.Session.isReleaseGradingValid) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"You need to select an overall grade !\",\n scrollToTop: false\n };\n } else if (!trainee.Session.isCertificateGradingValid) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"You need to grade all certificate exams!\",\n scrollToTop: false\n };\n }\n } else {\n isValid = true;\n }\n\n scope.info = info;\n return isValid;\n }\n\n function resetSignature(_trainee2) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgResetSignature.html',\n controller: 'TraineeSignatureModalCtrl',\n scope: scope,\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n trainee: function trainee() {\n return _trainee2;\n },\n signatureSuccess: function signatureSuccess() {\n return updateTraineeSignatures;\n }\n }\n });\n modalInstance.result.then(function (confirm) {\n if (confirm) {\n _trainee2.Session.Authorized = false;\n scope.trainees.find(function (x) {\n return x.CrewId == _trainee2.CrewId;\n }).Session.Authorized = false;\n updateTraineeSignatures();\n }\n });\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/Training/course.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CourseFactory', CourseFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CourseFactory\r\n * @description \r\n * Add, Update, Delete and Get Training Courses.\r\n * @ngInject\r\n */\n\n function CourseFactory(IndexedDBService, GroundDutyFactory, $http, apiUrl) {\n /**\r\n * Initialize Course\r\n * @memberof CourseFactory\r\n */\n function Course() {\n this.Id = null;\n }\n\n var objType = 'Courses';\n var objCallback = Course;\n var service = {\n setCoursesFromServer: setCoursesFromServer,\n setCoursesToStorage: setCoursesToStorage,\n //save all courses\n getCourseFromStorage: getCourseFromStorage,\n addCourseToStorage: addCourseToStorage,\n //update course\n saveOneCourseToStorage: saveOneCourseToStorage,\n //save course\n getCoursesFromStorage: getCoursesFromStorage,\n //get all\n updateCourseInfo: updateCourseInfo,\n updateFlightCourseInfo: updateFlightCourseInfo,\n getCoursesFromStorageByIds: getCoursesFromStorageByIds,\n setCourseOutdated: setCourseOutdated,\n upsertCourse: upsertCourse\n };\n /**\r\n * Get Course By Id\r\n * @memberof CourseFactory\r\n * @param {function} callback \r\n */\n\n function getCourseFromStorage(courseId, callback, errorCallback) {\n IndexedDBService.getById(objType, courseId).then(function (result) {\n callback(result);\n })[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Get Courses\r\n * @memberof CourseFactory\r\n * @param {function} callback \r\n */\n\n function getCoursesFromStorage(callback, errorCallback) {\n IndexedDBService.getAll(objType).then(function (results) {\n callback(results);\n })[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Get Course By Ids\r\n * @memberof CourseFactory\r\n * @param {function} callback \r\n */\n\n function getCoursesFromStorageByIds(courseIds, callback, errorCallback) {\n IndexedDBService.getAll(objType).then(function (results) {\n var selectedResults = [];\n results.forEach(function (result) {\n if (courseIds.includes(result.Id) && selectedResults.filter(function (x) {\n return x.Id == result.Id;\n }).length == 0) {\n selectedResults.push(result);\n }\n });\n callback(selectedResults);\n })[\"catch\"](errorCallback);\n }\n\n ;\n\n function updateCourseInfo(courseId, dutyId, callback, errorOnSaveCallback, errorOnNetwork) {\n var traingingApiURL = apiUrl + '/Training?courseId=' + courseId + '&dutyId=' + dutyId;\n $http.get(traingingApiURL, {\n 'Content-Type': 'application/json'\n }).then(function (data) {\n var course = data.data;\n course.FetchedTime = moment.utc().toJSON();\n var duty = GroundDutyFactory.getGroundDutyFromStorage(dutyId);\n course.FetchedDutyCodes = duty.RelatedGroundDuties.filter(function (x) {\n return !x.IsInstructor;\n }).map(function (x) {\n return String(x.GroundDutyNo);\n });\n course.LastFetchedDutyId = dutyId; //Upsert course in IndexDB \n\n upsertCourse(course, function (course) {\n callback(course);\n }, errorOnSaveCallback);\n })[\"catch\"](errorOnNetwork);\n }\n\n function updateFlightCourseInfo(crewRouteCourse, date, dutyNo, dutyDay, callback, errorOnSaveCallback, errorOnNetwork) {\n var traingingApiURL = apiUrl + '/Training/GetCrewRouteTraining';\n $http.post(traingingApiURL, crewRouteCourse, {\n 'Content-Type': 'application/json'\n }).then(function (data) {\n var course = data.data;\n course.FetchedTime = moment.utc().toJSON();\n course.FetchedCrewRoute = {\n date: date,\n dutyNo: dutyNo,\n dutyDay: dutyDay\n }; //Upsert course in IndexDB \n\n upsertCourse(course, function (course) {\n callback(course);\n }, errorOnSaveCallback);\n })[\"catch\"](errorOnNetwork);\n }\n\n function upsertCourse(course, callback, errorOnSaveCallback) {\n getCourseFromStorage(course.Id, function (localCourse) {\n if (localCourse) {\n saveOneCourseToStorage(course);\n } else {\n addCourseToStorage(course);\n }\n\n callback(course);\n }, errorOnSaveCallback);\n }\n\n function setCourseOutdated(courseId, callback, errorCallback) {\n getCourseFromStorage(courseId, function (localCourse) {\n if (localCourse) {\n localCourse.NeedsRefresh = true;\n saveOneCourseToStorage(localCourse);\n }\n\n if (callback) {\n callback();\n }\n }, errorCallback);\n }\n /**\r\n * Set Courses from server API \r\n * @memberof CourseFactory\r\n * @param {array} courses Courses Object\r\n * @param {array} courseIdsToSend Current courses of the storage\r\n * @param {string} lastSyncDate Last Sync Date \r\n */\n\n\n function setCoursesFromServer(courses, callback, errorCallback) {\n getCoursesFromStorage(function (localCourses) {\n // No courses found - Save All Incoming\n if (!localCourses || localCourses.length == 0) {\n setCoursesToStorage(courses);\n } else {\n for (var j = 0; j < courses.length; j++) {\n var IsCourseIncluded = false;\n\n for (var h = 0; h < localCourses.length; h++) {\n if (courses[j].Id == localCourses[h].Id) {\n IsCourseIncluded = true;\n break;\n }\n } //Update existing course\n\n\n if (IsCourseIncluded) {\n localCourses[h].Title = courses[j].Title; //Update title from sync\n\n saveOneCourseToStorage(localCourses[h]);\n } //Add a new Course\n else {\n addCourseToStorage(courses[j]);\n }\n }\n\n localCourses.filter(function (x) {\n return !courses.some(function (z) {\n return z.Id == x.Id;\n });\n }).forEach(function (course) {\n IndexedDBService.remove(objType, course.Id);\n });\n }\n });\n }\n /**\r\n * Set Courses\r\n * @memberof CourseFactory\r\n * @param {array} Courses A list of courses to set to indexedDB\r\n */\n\n\n function setCoursesToStorage(Courses, callback, errorCallback) {\n IndexedDBService.addAll(objType, Courses).then(callback)[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Add Course to Storage\r\n * @memberof CourseFactory\r\n * @param {object} Course\r\n */\n\n function addCourseToStorage(Course, callback, errorCallback) {\n IndexedDBService.add(objType, Course).then(callback)[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Update Course to Storage\r\n * @memberof CourseFactory\r\n * @param {object} Course\r\n */\n\n function saveOneCourseToStorage(Course, callback, errorCallback) {\n IndexedDBService.put(objType, Course).then(callback)[\"catch\"](errorCallback);\n }\n\n ;\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('FlightCourseCtrl', FlightCourseCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FlightCourseCtrl\r\n * @description \r\n *\r\n * @ngInject\r\n */\n\n function FlightCourseCtrl($route, $filter, $timeout, FlightSessionFactory, CrewRouteFactory, FlightFactory, GroundDutyFactory, CourseFactory, $scope, $location, $routeParams) {\n $scope.gotoCourse = gotoCourse;\n $scope.gotoCrewRoute = gotoCrewRoute;\n $scope.gotoFlight = gotoFlight;\n $scope.stickySelectedTrainee = stickySelectedTrainee;\n $scope.toggleView = toggleView;\n $scope.refreshCourse = refresh;\n $scope.courseTrainees = [];\n var courseId = Number($routeParams.courseId);\n var dutyNo = Number($routeParams.dutyNo);\n var dutyDay = Number($routeParams.dutyDay);\n $scope.viewFromFlight = Number($routeParams.flightId);\n var crewRouteDuty = CrewRouteFactory.getCrewRouteFromStorage(dutyNo, dutyDay);\n var date = $routeParams.date;\n crewRouteDuty.date = date;\n var crewRouteCourse = crewRouteDuty.Courses.find(function (x) {\n return x.CourseId == courseId && new moment(x.Date).isSame(date);\n });\n $scope.isEdit = false;\n $scope.loading = false;\n $scope.refreshSuccess = true; //show refresh icon\n\n if (!crewRouteDuty) {\n // go to dashboard if no groundDuty\n $location.path(\"/\");\n } else {\n $scope.flights = FlightFactory.getFlightsByDutyNo(dutyNo, dutyDay);\n $scope.currentFlight = $scope.flights.filter(function (f) {\n return f.FlightId == Number($routeParams.flightId);\n });\n var crewRouteTrainees = FlightSessionFactory.getCrewRouteFlightTrainees(dutyNo, dutyDay, crewRouteCourse.TrainingFlightIds); //Get Crew Route's course\n\n CourseFactory.getCourseFromStorage(courseId, function (savedCourse) {\n var dutyCourse = savedCourse;\n $scope.dutyCourse = dutyCourse;\n initCourse(false);\n });\n $scope.crewRouteDuty = crewRouteDuty;\n }\n\n function initCourse(afterRefresh) {\n var courseId = $scope.dutyCourse.Id;\n FlightSessionFactory.getSession(courseId, date, dutyNo, dutyDay, crewRouteCourse.TrainingFlightIds, afterRefresh, function (course) {\n if (course && !course.HasLimitedInfo) {\n $scope.availableCourse = true;\n $scope.selectedPhase = course.selectedPhase;\n $scope.trainees = course.CourseTrainees;\n course.SequenceWarning = false;\n }\n\n $scope.course = course;\n manageCourseStatus($scope.dutyCourse, course, afterRefresh);\n toggleView('History'); //default\n\n if ($scope.trainees) {\n stickySelectedTrainee(); //Check for status change (new trainees found on a submitted session (reset) || failed certificate trainees want to retake the test)\n\n if (afterRefresh && $scope.isCourseComplete && $scope.trainees.length) {\n CrewRouteFactory.setCoursePending(dutyNo, dutyDay, courseId, date);\n $scope.isCourseComplete = false;\n $route.reload();\n }\n }\n\n $scope.reload = false;\n $timeout(function () {\n $scope.reload = true;\n }, 100);\n });\n }\n\n function gotoCourse(course) {\n $location.path('/course/' + course.Id + '/' + groundDuty.DutyDateS + \"/\" + groundDuty.Id);\n }\n\n function gotoCrewRoute() {\n $location.path('/crewRoute/' + dutyNo + '/' + dutyDay);\n }\n\n function gotoFlight() {\n var flightId = Number($routeParams.flightId);\n $location.path('/flightinfo/' + flightId);\n }\n\n function refresh() {\n $scope.loading = true;\n\n if ($scope.isOffline) {\n $timeout(function () {\n $scope.loading = false;\n }, 100);\n $scope.refreshSuccess = false;\n $scope.availableCourseInfo = false;\n $scope.refreshErrorMsg = \"Online mode is required in order to get course. Please connect to the internet and try again.\";\n } else {\n CourseFactory.updateFlightCourseInfo(crewRouteCourse, date, dutyNo, dutyDay, function () {\n $scope.loading = false;\n $scope.refreshSuccess = true;\n $scope.availableCourseInfo = true;\n initCourse(true);\n $scope.reload = false;\n $timeout(function () {\n $scope.reload = true;\n }, 100);\n }, function () {\n $scope.loading = false;\n $scope.refreshSuccess = false;\n $scope.availableCourseInfo = false;\n $scope.refreshErrorMsg = \"Something went wrong! Please Try again.\";\n }, function (error) {\n console.log(error);\n $scope.loading = false;\n $scope.refreshSuccess = false;\n $scope.availableCourseInfo = false;\n $scope.refreshErrorMsg = \"Oops! Something went wrong!\"; //null exception!\n // if (error.data.errorMessage) {\n // $scope.refreshErrorMsg = error.data.errorMessage;\n // }\n });\n }\n }\n\n function manageCourseStatus(dutyCourse, course, afterRefresh) {\n // COMPLETED : has been submitted\n var isCourseComplete = crewRouteCourse.Status == \"Completed\"; // NEEDS SUBMIT : 1 hour has passed since the end of the course\n\n var now = moment.utc();\n\n if (!dutyCourse.IsCompleted) {\n var needsSubmit = false;\n var fetched = moment.utc(crewRouteDuty.DutyEnd);\n var duration = moment.duration(now.diff(fetched)).asHours();\n\n if (duration > 1) {\n needsSubmit = true;\n }\n } // LIMITED : no info available\n\n\n var isCourseLimited = !course || course.HasLimitedInfo || course.HasLimitedSession && !afterRefresh; // OUTDATED : NeedsRefresh || 18 hours since last refresh\n\n var isCourseOutdated = false;\n\n if (course && course.FetchedTime) {\n var now = moment.utc();\n var fetched = moment.utc(course.FetchedTime);\n var duration = moment.duration(now.diff(fetched)).asHours();\n\n if (duration > 18 || course.NeedsRefresh) {\n isCourseOutdated = true;\n }\n }\n\n var hasAdditionalTrainingRequest = false;\n\n if (course.SubmittedSessions && course.SubmittedSessions.length > 0) {\n if (course.SubmittedSessions.map(function (x) {\n return x.TraineesSessions.filter(function (y) {\n return y.UnderAdditionalTraining == true;\n }).length > 0;\n })) {\n hasAdditionalTrainingRequest = true;\n course.hasAdditionalTrainingRequest = true;\n }\n\n ;\n }\n\n var isUnderAdditionalTraining = false;\n\n if (course.SubmittedSessions && course.SubmittedSessions.length > 0) {\n if (course.SubmittedSessions.map(function (x) {\n return x.TraineesSessions.find(function (y) {\n return y.UnderAdditionalTraining == true;\n });\n })) {\n isUnderAdditionalTraining = true;\n course.isUnderAdditionalTraining = true;\n }\n\n ;\n }\n\n $scope.headerMsg = \"Refresh Course\";\n if (isCourseLimited) $scope.headerMsg = \"Fetch Course\";\n $scope.hasPendingTraining = !isCourseComplete;\n $scope.hasUnsetTraining = needsSubmit;\n $scope.isCourseLimited = isCourseLimited;\n $scope.isCourseComplete = isCourseComplete;\n $scope.isCourseOutdated = isCourseOutdated;\n $scope.hasAdditionalTrainingRequest = hasAdditionalTrainingRequest;\n $scope.hasNotifications = isCourseLimited || isCourseOutdated || isCourseComplete;\n }\n\n function stickySelectedTrainee() {\n if ($scope.trainees && $scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).length) {\n if ($scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).find(function (x) {\n return x.Session.selected;\n })) {\n $scope.selectedTrainee = $scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).find(function (x) {\n return x.Session.selected;\n });\n } else {\n $scope.selectedTrainee = $scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n })[0];\n }\n } else {\n $scope.selectedTrainee = null;\n }\n\n if ($scope.selectedTrainee) $scope.selectedTraineeBadge = {\n CrewId: $scope.selectedTrainee.CrewId\n };\n }\n\n function toggleView(mode) {\n $scope.viewMode = mode;\n }\n }\n})();\n\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('FlightSessionFactory', FlightSessionFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightSessionFactory\r\n * @description \r\n * Add, Update, Delete and Flight Sessions.\r\n * @ngInject\r\n */\n\n function FlightSessionFactory(IndexedDBService, CrewRouteFactory, FlightFactory, CourseFactory, $http, apiUrl, $filter) {\n /**\r\n * Initialize Session\r\n * @memberof FlightSessionFactory\r\n */\n function Session() {\n this.Id = null;\n }\n\n var objType = 'FlightSessions';\n var objCallback = Session;\n var service = {\n getAll: getAll,\n getSession: getSession,\n setSession: setSession,\n updateSession: updateSession,\n getSessionTrainees: getSessionTrainees,\n submitSession: submitSession,\n remove: remove,\n getCrewRouteFlightTrainees: getCrewRouteFlightTrainees,\n applyTraineeInfoToSession: applyTraineeInfoToSession\n };\n /**\r\n * Get all flight training sessions\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\n\n function getAll(callback) {\n IndexedDBService.getAll(objType).then(function (results) {\n callback(results);\n });\n }\n\n ;\n /**\r\n * Get session By day and courseId\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\n\n function getSession(courseId, day, dutyNo, dutyDay, trainingFlightIds, afterRefresh, callback, errorCallback) {\n IndexedDBService.getById(objType, [day, courseId, dutyNo, dutyDay]).then(function (session) {\n CourseFactory.getCourseFromStorage(courseId, function (course) {\n if (course && !course.HasLimitedInfo && course.CrewCoursePhases && course.CourseTrainees) {\n mergeCourseWithSession(course, session, dutyNo, dutyDay, trainingFlightIds, afterRefresh);\n }\n\n callback(course);\n }, errorCallback);\n })[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Remove session By day, dutyNo, dutyDay and courseId\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\n\n function remove(courseId, day, dutyNo, dutyDay, callback, errorCallback) {\n IndexedDBService.remove(objType, [day, courseId, dutyNo, dutyDay]).then(callback)[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Get session Trainees By day and courseId\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\n\n function getSessionTrainees(courseId, day, dutyNo, dutyDay, callback, errorCallback) {\n IndexedDBService.getById(objType, [day, courseId, dutyNo, dutyDay]).then(function (session) {\n var trainees = session && session.trainees ? session.trainees : [];\n callback(trainees);\n })[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Set session\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\n\n function setSession(session, callback, errorCallback) {\n IndexedDBService.getById(objType, [session.day, session.courseId, session.dutyNo, session.dutyDay]).then(function (result) {\n if (result) {\n saveSessionToStorage(session).then(callback)[\"catch\"](errorCallback);\n ;\n } else {\n addSessionToStorage(session).then(callback)[\"catch\"](errorCallback);\n }\n })[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Set session\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\n\n function updateSession(trainees, session, courseId, day, dutyNo, dutyDay, callback, errorCallback) {\n IndexedDBService.getById(objType, [day, courseId, dutyNo, dutyDay]).then(function (localSession) {\n var isNewSession = false;\n\n if (!localSession) {\n localSession = {\n courseId: courseId,\n day: day,\n dutyNo: dutyNo,\n dutyDay: dutyDay,\n trainees: []\n };\n isNewSession = true;\n } else {\n localSession.trainees = [];\n }\n\n if (session) {\n localSession.Media = session.Media;\n localSession.ReleasedPhase = session.ReleasedPhase;\n localSession.PilotFunctions = session.PilotFunctions;\n localSession.TraineeEligibilty = session.TraineeEligibilty;\n }\n\n trainees.forEach(function (trainee) {\n localSession.trainees.push(trainee);\n });\n\n if (isNewSession) {\n addSessionToStorage(localSession).then(callback)[\"catch\"](errorCallback);\n } else {\n saveSessionToStorage(localSession).then(callback)[\"catch\"](errorCallback);\n }\n })[\"catch\"](errorCallback);\n }\n\n function mergeCourseWithSession(course, session, dutyNo, dutyDay, trainingFlightIds, afterRefresh) {\n course.HasLimitedSession = session == undefined;\n var hasPreviousSessions = mergeSyllabusWithHistory(course.CourseTrainees, course.CrewCoursePhases);\n filterTraineesByEligibility(dutyNo, dutyDay, course, trainingFlightIds, session, afterRefresh);\n course.CrewCoursePhases.forEach(function (phase) {\n calculatePhaseStatus(phase, course);\n });\n course.selectedPhase = getSelectedPhase(course); // Calculate eligible trainees phase status\n\n course.CourseTrainees.forEach(function (trainee) {\n var traineePhase = trainee.Phases.find(function (x) {\n return x.PhaseId == course.selectedPhase.PhaseId;\n });\n\n if (traineePhase) {\n trainee.ActivePhaseStatus = traineePhase.PhaseStatus;\n } else {\n trainee.ActivePhaseStatus = \"Pending\";\n }\n\n trainee.Selectable = trainee.ActivePhaseStatus == \"InProgress\";\n }); // Non InProgress trainees will be marked as NonEligible (remove further ahead trainees on multiple InProgress phases)\n\n course.CourseTrainees.filter(function (x) {\n return !x.Selectable;\n }).forEach(function (invalidPhaseTrainee) {\n invalidPhaseTrainee.EligibilityStatus = false;\n invalidPhaseTrainee.EligibilityDesc = \"AlreadySubmitted\";\n course.NonEligibleTrainees.push(invalidPhaseTrainee);\n });\n course.CourseTrainees = course.CourseTrainees.filter(function (x) {\n return x.EligibilityStatus;\n }); // Get trainee sessions\n\n course.CourseTrainees.forEach(function (trainee) {\n var sessionTrainee = session ? session.trainees.find(function (x) {\n return x.CrewId == trainee.CrewId;\n }) : null;\n\n if (sessionTrainee) {\n trainee.Session = sessionTrainee.Session;\n } else {\n trainee.Session = {\n Released: course.selectedPhase.ModuleType == \"Training\" ? false : true,\n CrewId: trainee.CrewId,\n Items: [],\n Absent: false,\n DayGrading: {\n Comments: null,\n Grade: null,\n Competences: []\n },\n ReleaseGrading: {\n Comments: null,\n Grade: null,\n Competences: []\n },\n NeedsAdditionalTraining: false,\n AdditionalTrainingRemarks: null,\n CompleteAdditionalTraining: false\n };\n }\n });\n /* Set default values for release option\r\n Training Modules: 'No' release as default\r\n Check Module: 'Yes' release as default\r\n */\n\n course.ReleasedPhase = course.selectedPhase.ModuleType == \"Training\" ? false : true;\n\n if (session) {\n course.Media = session.Media;\n course.ReleasedPhase = session.ReleasedPhase;\n course.PilotFunctions = session.PilotFunctions;\n course.TraineeEligibilty = session.TraineeEligibilty;\n }\n }\n\n function getSelectedPhase(course) {\n var hasSelectedPhase = false;\n var phases = course.CrewCoursePhases;\n phases.forEach(function (phase, index, array) {\n phase.isFirst = index == 0;\n phase.isLast = index + 1 == array.length; // Select the first InProgress & selected phase\n\n if (!hasSelectedPhase && phase.Status == \"InProgress\" && phase.isSelected) {\n phase.Selected = true;\n hasSelectedPhase = true;\n }\n }); // Select the first InProgress phase\n\n if (!hasSelectedPhase && phases.some(function (x) {\n return x.Status == \"InProgress\";\n })) {\n phases.find(function (x) {\n return x.Status == \"InProgress\";\n }).Selected = true;\n hasSelectedPhase = true;\n }\n\n if (!hasSelectedPhase) {\n phases.find(function (x) {\n return x.isFirst;\n }).Selected = true;\n }\n\n var selectedPhase = phases.find(function (x) {\n return x.Selected;\n });\n return selectedPhase;\n }\n\n function filterTraineesByEligibility(dutyNo, dutyDay, course, trainingFlightIds, session, afterRefresh) {\n var _course$CourseTrainee;\n\n // Trainee Eligiblity cases\n // 1. After refresh - Save newly fetched eligibility in session\n // 2. No refresh & Session exists - Get last fetched eligibility from session\n // 3. No refresh & No session exists - Rely on previously fetched eligibility (different duty - same course)\n var traineeEligibility = course.TraineeEligibilty;\n\n if (!afterRefresh && session && session.TraineeEligibilty) {\n traineeEligibility = session.TraineeEligibilty;\n }\n\n if (session) session.TraineeEligibilty = traineeEligibility; //update session eligibility\n // Get crew route trainees without any training records\n\n var trainees = getCrewRouteFlightTrainees(dutyNo, dutyDay, trainingFlightIds);\n var inactiveTrainees = trainees.filter(function (x) {\n return !course.CourseTrainees.some(function (z) {\n return z.CrewId == x.CrewId;\n });\n }); //Exclude Non valid trainees\n\n var eligibleTraineeIds = Object.keys(traineeEligibility).filter(function (x) {\n return traineeEligibility[x] == \"NotStarted\" || traineeEligibility[x] == \"ValidPhase\" || traineeEligibility[x] == \"FailedCertificate\";\n }).map(Number); // traineeEligibility[x] == \"UnderAdditionalTraining\" |\n\n var eligibleTrainees = inactiveTrainees.filter(function (x) {\n return eligibleTraineeIds.includes(x.CrewId);\n });\n eligibleTrainees.forEach(function (trainee) {\n trainee.EligibilityStatus = true;\n });\n createNewPhaseTrainees(dutyNo, dutyDay, trainingFlightIds, course, eligibleTrainees); // Merge eligibleTrainees (inactive) with CourseTrainees (eligible & active)\n\n course.CourseTrainees.forEach(function (trainee) {\n trainee.EligibilityStatus = true;\n });\n\n (_course$CourseTrainee = course.CourseTrainees).push.apply(_course$CourseTrainee, _toConsumableArray(eligibleTrainees)); // Non eligible trainees\n\n\n var nonEligibleTrainees = inactiveTrainees.filter(function (x) {\n return !eligibleTraineeIds.includes(x.CrewId);\n });\n course.NonEligibleTrainees = nonEligibleTrainees;\n nonEligibleTrainees.forEach(function (trainee) {\n trainee.EligibilityStatus = false;\n trainee.EligibilityDesc = traineeEligibility[trainee.CrewId];\n }); // Result:\n // CourseTrainees = eligible trainees (active or new)\n // Non EligibleTrainees\n }\n /**\r\n * Create first phase foreach trainee\r\n * @param {object} groundDuty\r\n * @param {object} course\r\n * @param {array} trainees Eligible trainees that haven't yet started training\r\n */\n\n\n function createNewPhaseTrainees(dutyNo, dutyDay, trainingFlightIds, course, trainees) {\n var flights = FlightFactory.getFlightsByDutyNo(dutyNo, dutyDay).filter(function (f) {\n return trainingFlightIds.some(function (z) {\n return z == f.FlightId;\n });\n }); //Match TrainingIndicators with PhaseDutyNos\n\n var crewCoursePhaseDutyNos = [];\n var crewrouteTrainingIndicators = [];\n course.CrewCoursePhases.forEach(function (coursePhase) {\n crewCoursePhaseDutyNos = crewCoursePhaseDutyNos.concat(coursePhase.FlightTrainingIndicators);\n });\n flights.forEach(function (flight) {\n crewrouteTrainingIndicators.push(flight.TrainingIndicatorId.toString());\n });\n var relatedDutyNos = crewCoursePhaseDutyNos.filter(function (x) {\n return crewrouteTrainingIndicators.includes(x);\n });\n var relatedPhases = course.CrewCoursePhases.filter(function (x) {\n return x.FlightTrainingIndicators.some(function (fti) {\n return relatedDutyNos.includes(fti);\n });\n }); //From related phases, select first in order\n\n relatedPhases = $filter('orderBy')(relatedPhases, 'OrderNo');\n var firstPhase = relatedPhases[0];\n trainees.forEach(function (trainee) {\n trainee.Phases = [{\n PhaseId: firstPhase.PhaseId,\n PhaseStatus: \"InProgress\",\n RepeatRequestedItems: [],\n isSelected: true //selectedPhase\n\n }];\n });\n }\n\n function getCrewRouteFlightTrainees(dutyNo, dutyDay, trainingFlightIds) {\n var flights = FlightFactory.getFlightsByDutyNo(dutyNo, dutyDay).filter(function (f) {\n return trainingFlightIds.some(function (z) {\n return z == f.FlightId;\n });\n });\n var trainees = [];\n flights.forEach(function (flight) {\n flight.crew.filter(function (x) {\n return x.IsTrainee;\n }).forEach(function (trainee) {\n if (!trainees.some(function (x) {\n return x.id == trainee.id;\n })) {\n //do not push duplicates : trainees that are in multiple flights\n trainees.push(trainee);\n }\n });\n });\n trainees.forEach(function (trainee) {\n trainee.CrewId = trainee.id;\n trainee.Id = trainee.id;\n trainee.Name = trainee.name;\n trainee.AimsId = trainee.aimsId;\n });\n return trainees;\n }\n\n function calculatePhaseStatus(phase, course) {\n course.CourseTrainees.forEach(function (trainee) {\n var traineePhase = trainee.Phases.find(function (x) {\n return x.PhaseId == phase.PhaseId;\n });\n\n if (traineePhase && traineePhase.PhaseStatus == \"InProgress\") {\n phase.Status = \"InProgress\";\n } else if (!traineePhase && phase.Status != \"InProgress\") {\n phase.Status = \"Pending\";\n } else if (traineePhase && traineePhase.PhaseStatus == \"Completed\" && phase.Status != \"InProgress\") {\n phase.Status = \"Completed\";\n } //Selected phase, If at least one trainee has it selected\n\n\n if (traineePhase && !phase.isSelected) {\n phase.isSelected = traineePhase.isSelected;\n }\n });\n }\n\n function mergeSyllabusWithHistory(trainees, phases) {\n var flatSullabusItems = [];\n trainees.forEach(function (trainee) {\n trainee.Phases.forEach(function (phase) {\n phase.Sessions.forEach(function (session) {\n session.Items.forEach(function (item) {\n var flatItem = createFlatHistorySullabusItem(trainee, phase, session, item);\n flatSullabusItems.push(flatItem);\n });\n });\n });\n });\n phases.filter(function (x) {\n return x.Syllabus;\n }).forEach(function (phase, index, array) {\n phase.Syllabus.SyllabusItems.forEach(function (syllabusItem) {\n syllabusItem.History = flatSullabusItems.filter(function (item) {\n return item.ItemId == syllabusItem.Id;\n });\n });\n });\n var hasPreviousSessions = flatSullabusItems.length > 0;\n return hasPreviousSessions;\n }\n\n function createFlatHistorySullabusItem(trainee, phase, session, item) {\n var flatItem = {\n CrewId: trainee.CrewId,\n PhaseId: phase.PhaseId,\n SessionId: session.SessionId,\n SessionComments: session.SessionComments,\n SubmissionDate: item.SubmissionDate,\n RepeatRequired: item.RepeatRequired,\n Tries: item.Tries,\n ItemId: item.SyllabusItemId,\n Grade: session.Grade,\n GradeType: session.GradeType,\n InstructorName: session.InstructorName,\n InstructorAimsId: session.InstructorAimsId\n };\n return flatItem;\n }\n /**\r\n * Add Session to Storage\r\n * @memberof FlightSessionFactory\r\n * @param {object} Session\r\n */\n\n\n function addSessionToStorage(session) {\n return IndexedDBService.add(objType, session);\n }\n\n ;\n /**\r\n * Update Session to Storage\r\n * @memberof FlightSessionFactory\r\n * @param {object} Session\r\n */\n\n function saveSessionToStorage(session) {\n return IndexedDBService.put(objType, session);\n }\n\n ;\n\n function submitSession(submittedSession, callback) {\n var traingingApiURL = apiUrl + '/Training/SubmitTraining';\n return $http.post(traingingApiURL, submittedSession, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n\n function applyTraineeInfoToSession(course, courseId, day, dutyNo, dutyDay, callback, errorCallback) {\n IndexedDBService.getById(objType, [day, courseId, dutyNo, dutyDay]).then(function (localSession) {\n var isNewSession = false;\n\n if (!localSession) {\n localSession = {\n courseId: courseId,\n day: day,\n dutyNo: dutyNo,\n dutyDay: dutyDay,\n trainees: [],\n TraineeEligibilty: course.TraineeEligibilty,\n CourseTrainees: course.CourseTrainees\n };\n isNewSession = true;\n } else {\n localSession.CourseTrainees = course.CourseTrainees;\n localSession.TraineeEligibilty = course.TraineeEligibilty;\n }\n\n if (isNewSession) {\n addSessionToStorage(localSession).then(callback)[\"catch\"](errorCallback);\n } else {\n saveSessionToStorage(localSession).then(callback)[\"catch\"](errorCallback);\n }\n })[\"catch\"](errorCallback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('grading', grading);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name grading\r\n * @restrict E\r\n * @description\r\n * Implementation of overall grading\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function grading() {\n function link(scope, element, attrs) {\n scope.getRemainingCharacters = getRemainingCharacters;\n scope.validateGrading = validateGrading;\n scope.filterValidTrainees = filterValidTrainees;\n scope.filterTrainee = filterTrainee;\n scope.saveComment = saveComment;\n scope.isDayGrading = scope.type == \"day\";\n scope.hasCertificateExam = scope.type == \"certificate\";\n scope.isCheck = scope.phase == \"Check\"; //Separate DayGrading and ReleaseGrading \n\n scope.sessions = [];\n scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).forEach(function (trainee) {\n var session = scope.isDayGrading ? trainee.Session.DayGrading : trainee.Session.ReleaseGrading;\n session.Name = trainee.Name;\n session.AimsId = trainee.AimsId;\n session.CrewId = trainee.CrewId;\n\n if (scope.isDayGrading || !scope.isDayGrading && !scope.isCheck && trainee.AvailableRelease || !scope.isDayGrading && scope.isCheck) {\n scope.sessions.push(session);\n }\n });\n scope.sessions.forEach(function (traineeSession) {\n validateGrading(traineeSession);\n });\n filterValidTrainees();\n /**\r\n * Calculate remaining characters for comment input\r\n * @param {string} text \r\n * @param {number} max \r\n */\n\n function getRemainingCharacters(text, max) {\n if (typeof text === \"undefined\" || text === null) return '';\n if (typeof max === \"undefined\" || max === null || max < 0 || !max) max = 4000;\n var length = text.length;\n return 'characters left: ' + (max - length);\n }\n\n function validateGrading(trainee) {\n trainee.isGradeValid = trainee.Grade != null && trainee.Grade != undefined;\n }\n\n function filterValidTrainees() {\n scope.sessions.forEach(function (traineeSession) {\n traineeSession.isValid = traineeSession.isGradeValid && (!scope.settings.Competences.length || traineeSession.isCompetenceValid);\n });\n }\n\n function filterTrainee() {\n return function (trainee) {\n var showTrainee = true;\n\n if (scope.selected) {\n //individual grading view: filter selected\n showTrainee = scope.selected.CrewId == trainee.CrewId;\n }\n\n return showTrainee;\n };\n }\n\n function saveComment() {\n scope.commentInput();\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/Training/grading.tpl.html',\n scope: {\n trainees: \"=\",\n settings: \"=\",\n type: \"@\",\n phase: \"=\",\n selected: \"=\",\n commentInput: \"&onCommentInput\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('GroundCourseCtrl', GroundCourseCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name GroundCourseCtrl\r\n * @description \r\n *\r\n * @ngInject\r\n */\n\n function GroundCourseCtrl($route, $filter, $timeout, TrainingSessionFactory, CrewRouteFactory, FlightFactory, GroundDutyFactory, CourseFactory, $scope, $location, $routeParams) {\n $scope.gotoCourse = gotoCourse;\n $scope.gotoGroundDuty = gotoGroundDuty;\n $scope.stickySelectedTrainee = stickySelectedTrainee;\n $scope.toggleView = toggleView;\n $scope.refreshCourse = refresh;\n $scope.courseTrainees = [];\n var courseId = Number($routeParams.courseId);\n var groundDutyId = Number($routeParams.dutyId);\n var groundDuty = GroundDutyFactory.getGroundDutyFromStorage(groundDutyId);\n $scope.isEdit = false;\n $scope.loading = false;\n $scope.allAbsent = false;\n $scope.refreshSuccess = true; //show refresh icon\n\n if (!groundDuty) {\n // go to dashboard if no groundDuty\n $location.path(\"/\");\n } else {\n var date = groundDuty.DutyDateS;\n\n if (groundDuty.RelatedGroundDuties) {\n var courses = GroundDutyFactory.getGroundDutyActiveCourses(groundDutyId);\n\n if (courses.length) {\n CourseFactory.getCourseFromStorage(courseId, function (dutyCourse) {\n $scope.dutyCourse = dutyCourse;\n initCourse(false);\n });\n }\n }\n\n $scope.groundDuty = groundDuty;\n $scope.groundDutyId = groundDutyId;\n }\n\n function initCourse(afterRefresh) {\n var courseId = $scope.dutyCourse.Id;\n TrainingSessionFactory.getSession(courseId, date, groundDutyId, afterRefresh, function (course) {\n if (course && !course.HasLimitedInfo) {\n $scope.availableCourse = true;\n $scope.selectedPhase = course.selectedPhase;\n $scope.trainees = course.CourseTrainees; //only eligible trainees\n\n course.SequenceWarning = false;\n }\n\n $scope.course = course;\n manageCourseStatus($scope.dutyCourse, course, afterRefresh);\n toggleView('History'); //default\n\n if ($scope.trainees) {\n applyAttendanceFromGroundDuty(groundDuty, $scope.trainees);\n stickySelectedTrainee();\n\n if ($scope.trainees.length && !$scope.trainees.some(function (x) {\n return !x.Session.Absent;\n })) {\n $scope.allAbsent = true;\n } //Check for status change (new trainees found on a submitted session (reset) || failed certificate trainees want to retake the test)\n\n\n if (afterRefresh && $scope.isCourseComplete && $scope.trainees.length) {\n GroundDutyFactory.setCoursePending(groundDutyId, courseId);\n $scope.isCourseComplete = false;\n $route.reload();\n }\n }\n\n $scope.reload = false;\n $timeout(function () {\n $scope.reload = true;\n }, 100);\n });\n }\n\n function applyAttendanceFromGroundDuty(groundDuty, trainees) {\n groundDuty.Trainees.forEach(function (related) {\n related.CrewMembers.forEach(function (crew) {\n var trainee = trainees.find(function (x) {\n return x.CrewId == crew.Id;\n });\n\n if (trainee) {\n trainee.Session.Absent = crew.Absent;\n }\n });\n });\n }\n\n function gotoCourse(course) {\n $location.path('/course/' + course.Id + '/' + groundDuty.DutyDateS + \"/\" + groundDuty.Id);\n }\n\n function refresh() {\n $scope.loading = true;\n\n if ($scope.isOffline) {\n $timeout(function () {\n $scope.loading = false;\n }, 100);\n $scope.refreshSuccess = false;\n $scope.availableCourseInfo = false;\n $scope.refreshErrorMsg = \"Online mode is required in order to get course. Please connect to the internet and try again.\";\n } else {\n CourseFactory.updateCourseInfo($scope.dutyCourse.Id, groundDutyId, function () {\n $scope.loading = false;\n $scope.refreshSuccess = true;\n $scope.availableCourseInfo = true;\n initCourse(true);\n $scope.reload = false;\n $timeout(function () {\n $scope.reload = true;\n }, 100);\n }, function () {\n $scope.loading = false;\n $scope.refreshSuccess = false;\n $scope.availableCourseInfo = false;\n $scope.refreshErrorMsg = \"Something went wrong! Please Try again.\";\n }, function (error) {\n console.log(error);\n $scope.loading = false;\n $scope.refreshSuccess = false;\n $scope.availableCourseInfo = false;\n $scope.refreshErrorMsg = \"Oops! Something went wrong!\"; //null exception!\n // if (error.data.errorMessage) {\n // $scope.refreshErrorMsg = error.data.errorMessage;\n // }\n });\n }\n }\n\n function manageCourseStatus(dutyCourse, course, afterRefresh) {\n // COMPLETED : has been submitted\n var isCourseComplete = courses.find(function (x) {\n return x.CourseId == dutyCourse.Id && x.Status == \"Completed\";\n }) != null; // NEEDS SUBMIT : 1 hour has passed since the end of the course\n\n var now = moment.utc();\n\n if (!dutyCourse.IsCompleted) {\n var needsSubmit = false;\n var fetched = moment.utc(groundDuty.DutyEnd);\n var duration = moment.duration(now.diff(fetched)).asHours();\n\n if (duration > 1) {\n needsSubmit = true;\n }\n } // LIMITED : no info available\n\n\n var isCourseLimited = !course || course.HasLimitedInfo || course.HasLimitedSession && !afterRefresh; // OUTDATED : NeedsRefresh || 18 hours since last refresh\n\n var isCourseOutdated = false;\n\n if (course && course.FetchedTime) {\n var now = moment.utc();\n var fetched = moment.utc(course.FetchedTime);\n var duration = moment.duration(now.diff(fetched)).asHours();\n\n if (duration > 18 || course.NeedsRefresh) {\n isCourseOutdated = true;\n }\n } // ADDITIONAL TRAINING : One trainee, at least, is under additional training\n\n\n var hasAdditionalTrainingRequest = false; // if (course.selectedPhase.NeedsAdditionalTraining) \n // hasAdditionalTrainingRequest = true; \n // course.hasAdditionalTrainingRequest = true;\n\n $scope.headerMsg = \"Refresh Course\";\n if (isCourseLimited) $scope.headerMsg = \"Fetch Course\";\n $scope.hasPendingTraining = !isCourseComplete;\n $scope.hasUnsetTraining = needsSubmit;\n $scope.isCourseLimited = isCourseLimited;\n $scope.isCourseComplete = isCourseComplete;\n $scope.isCourseOutdated = isCourseOutdated;\n $scope.hasNotifications = isCourseLimited || isCourseOutdated || isCourseComplete;\n $scope.hasAdditionalTrainingRequest = hasAdditionalTrainingRequest;\n }\n\n function gotoGroundDuty() {\n $location.path('/groundDuty/' + groundDutyId);\n }\n\n function stickySelectedTrainee() {\n var availableRelease = $scope.selectedPhase.ModuleType == \"Check\" || !$scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (tr) {\n return tr.Session.Items.some(function (i) {\n return i.Status == \"Pending\";\n });\n });\n var individualGrading = $scope.trainees && $scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).length && $scope.selectedPhase && ($scope.selectedPhase.Syllabus && $scope.selectedPhase.Syllabus.IsGradable || $scope.selectedPhase.HasDayGrading || $scope.selectedPhase.HasReleaseGrading && availableRelease || RequiresTraineeSignature());\n\n if (individualGrading) {\n if ($scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).find(function (x) {\n return x.Session.selected;\n })) {\n $scope.selectedTrainee = $scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).find(function (x) {\n return x.Session.selected;\n });\n } else {\n $scope.selectedTrainee = $scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n })[0];\n }\n } else {\n $scope.selectedTrainee = null;\n }\n\n if ($scope.selectedTrainee) $scope.selectedTraineeBadge = {\n CrewId: $scope.selectedTrainee.CrewId\n };\n }\n\n function RequiresTraineeSignature() {\n // End of session signature\n var endOfSessionSignature = $scope.selectedPhase.DayGrading.TraineeSignature; // End of module signature\n\n var endOfModuleSignature = $scope.course.ReleasedPhase && $scope.selectedPhase.ReleaseGrading.TraineeSignature;\n return endOfSessionSignature || endOfModuleSignature;\n }\n\n function toggleView(mode) {\n $scope.viewMode = mode;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('instructions', instructions);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name notifications\r\n * @restrict E\r\n * @description\r\n * Show selected module's trainee & instructor instructions\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function instructions($filter, $routeParams, $location, UserFactory) {\n function link(scope, attrs) {\n scope.warningMessageText = \"\";\n scope.viewModuleHistory = viewModuleHistory;\n\n if (!scope.course.isParallel) {\n var currentActiveOrderNo = scope.selectedPhase.OrderNo;\n scope.course.CrewCoursePhases.forEach(function (phase) {\n if (phase.OrderNo < currentActiveOrderNo && phase.Status != \"Completed\") {\n phase.SequentialWarning = true;\n } //check if phase has any history\n\n\n var oldSessions = [];\n scope.trainees.filter(function (x) {\n return !x.Session.Absent;\n }).forEach(function (trainee) {\n var historyPhase = trainee.Phases.find(function (x) {\n return x.PhaseId == phase.PhaseId;\n });\n if (historyPhase && historyPhase.Sessions) oldSessions = oldSessions.concat(historyPhase.Sessions);\n });\n phase.hasHistory = oldSessions.length > 0;\n });\n }\n\n scope.course.CrewCoursePhases.forEach(function (phase) {\n phase.StatusClass = '';\n\n if (phase.SequentialWarning) {\n phase.StatusClass = \"panel-danger border-left-red\";\n phase.BtnClass = \"bg-red text-white\";\n } else if (phase.Status == 'InProgress') {\n phase.StatusClass = \"border-left-blue\";\n phase.TextClass = \"text-blue\";\n phase.BtnClass = \"bg-blue text-white\";\n } else if (phase.Status == 'Pending') {\n phase.StatusClass = \"border-left-gray \";\n phase.TextClass = \"text-gray\";\n phase.BtnClass = \"bg-gray text-white\";\n } else if (phase.Status == 'Completed') {\n phase.StatusClass = \"border-left-green\";\n phase.TextClass = \"text-green\";\n phase.BtnClass = \"bg-green text-white\";\n }\n\n if (phase.PhaseId == scope.selectedPhase.PhaseId) {\n phase.StatusClass = phase.StatusClass + \" panel-info\";\n }\n });\n var furtherAheadPhases = [];\n furtherAheadPhases = scope.course.CrewCoursePhases.filter(function (x) {\n return x.SequentialWarning;\n });\n furtherAheadPhases = $filter('orderBy')(furtherAheadPhases, 'OrderNo');\n\n if (furtherAheadPhases.length > 0) {\n scope.course.SequenceWarning = true;\n scope.warningMessageText = \"\" + furtherAheadPhases[furtherAheadPhases.length - 1].Title + \" is not completed. Confirm that you want to continue to \" + scope.selectedPhase.Title + \".\";\n }\n\n scope.traineeInstructions = scope.selectedPhase.TraineeInstructions;\n scope.examinerInstructions = scope.selectedPhase.ExaminerInstructions;\n scope.isInstructorView = false;\n var traineesAimsIds = scope.trainees.map(function (x) {\n return x.AimsId;\n });\n var user = UserFactory.getUser();\n\n if (!traineesAimsIds.includes(user.aimsId)) {\n scope.isInstructorView = true;\n }\n\n scope.status = {\n isInstructorOpen: true,\n isTraineeOpen: false\n };\n scope.continueSubmission = continueSubmission;\n scope.cancelSubmission = cancelSubmission;\n\n function continueSubmission() {\n scope.course.SequenceWarning = false;\n }\n\n function cancelSubmission() {\n if (scope.isGround) {\n gotoGroundDuty();\n } else {\n gotoCrewRoute();\n }\n }\n\n function gotoGroundDuty() {\n $location.path('/groundDuty/' + Number($routeParams.dutyId));\n }\n\n function gotoCrewRoute() {\n var dutyNo = scope.crewRouteDuty.DutyNo;\n var dutyDay = scope.crewRouteDuty.DutyDay;\n $location.path('/crewRoute/' + dutyNo + '/' + dutyDay);\n }\n\n function viewModuleHistory(phaseId) {\n var courseId = Number($routeParams.courseId);\n var dutyId = Number($routeParams.dutyId);\n var date = $routeParams.date;\n\n if (dutyId) {\n $location.path('/groundHistory/' + courseId + '/' + dutyId + '/' + date + '/' + phaseId);\n } else {\n var dutyNo = scope.crewRouteDuty.DutyNo;\n var dutyDay = scope.crewRouteDuty.DutyDay;\n $location.path('/flightHistory/' + courseId + '/' + dutyNo + '/' + dutyDay + '/' + date + '/' + phaseId);\n }\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: \"views/Training/instructions.tpl.html\",\n scope: false,\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('media', media);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name ground Media\r\n * @restrict E\r\n * @description\r\n * Initialize panel with media of training selection, aircraft types & synthetic devices\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function media($location, CourseFactory) {\n function link($scope, attrs) {\n $scope.addAircraftRow = addAircraftRow;\n $scope.removeAircraftRow = removeAircraftRow;\n $scope.showDowntimeDuration = showDowntimeDuration;\n $scope.clearDowntimeDuration = clearDowntimeDuration;\n $scope.isObjectEmpty = isObjectEmpty;\n $scope.downtimeDuration = {\n radioValue: 'false',\n show: false,\n minutes: null\n };\n $scope.sessionDuration = $scope.groundDuty ? (new Date($scope.groundDuty.DutyEnd) - new Date($scope.groundDuty.DutyBegin)) / (1000 * 60) : undefined;\n $scope.downtimeDurationValueChanged = downtimeDurationValueChanged;\n initializeMedia();\n $scope.filterSyntheticDevices = filterSyntheticDevices;\n\n function isObjectEmpty(obj) {\n return Object.keys(obj).length === 0;\n }\n\n function initializeMedia() {\n if ($scope.course) {\n if (!$scope.course.Media) {\n // Create Media object\n $scope.course.Media = {\n inputAircrafts: [],\n selectedAircraft: {\n selection: undefined\n },\n selectedDevice: {\n selection: undefined\n },\n radioModel: \"\"\n };\n }\n\n if ($scope.course.Media.radioModel == \"\" || mediaRemoved()) {\n //Auto select media on init or if selection was removed in admin settings\n if ($scope.selectedPhase.InSimulator) $scope.course.Media.radioModel = \"Simulator\";\n if ($scope.selectedPhase.InAircraft) $scope.course.Media.radioModel = \"Aircraft\";\n if ($scope.selectedPhase.InClassroom) $scope.course.Media.radioModel = \"Classroom\";\n }\n\n if ($scope.selectedPhase.InSimulator) {\n // Check if training centers exist\n if ($scope.course.TrainingCenters && $scope.course.TrainingCenters.length > 0) {\n var defaultCenter = $scope.course.TrainingCenters.find(function (x) {\n return x.IsDefault;\n });\n\n if (defaultCenter) {\n $scope.course.selectedTrainingCenter = defaultCenter.Id;\n filterSyntheticDevices(defaultCenter.Id);\n } else {\n // If no default center, select \"No Center\"\n $scope.course.selectedTrainingCenter = 'No Center'; // No need to filter devices based on training center, show all devices\n\n filterSyntheticDevices('No Center');\n }\n } // Auto-select the first device if not already selected and devices exist\n\n\n if ($scope.course.SyntheticDevices && !isObjectEmpty($scope.course.SyntheticDevices)) {\n if (!$scope.course.Media.selectedDevice) {\n $scope.course.Media.selectedDevice = {};\n }\n\n if (!$scope.course.Media.selectedDevice.selection) {\n // Select the first available device\n $scope.course.Media.selectedDevice.selection = Object.keys($scope.course.SyntheticDevices)[0];\n }\n } else {\n // No devices available, clear the selection\n $scope.course.Media.selectedDevice.selection = undefined;\n }\n } // Create downtime duration object\n\n\n $scope.downtimeDuration = {\n radioValue: 'false',\n show: false,\n minutes: null\n };\n }\n }\n\n function filterSyntheticDevices(trainingCenterId) {\n if (!$scope.course.AllSyntheticDevices) {\n return;\n }\n\n if (trainingCenterId && trainingCenterId !== 'No Center') {\n $scope.course.SyntheticDevices = $scope.course.AllSyntheticDevices.filter(function (device) {\n return device.TrainingCenterId == trainingCenterId;\n });\n\n if ($scope.course.SyntheticDevices && $scope.course.SyntheticDevices.length > 0) {\n var defaultDevice = $scope.course.SyntheticDevices.find(function (device) {\n return device.IsDefault;\n });\n\n if (defaultDevice) {\n $scope.course.Media.selectedDevice.selection = defaultDevice.Id;\n } else {\n $scope.course.Media.selectedDevice.selection = null;\n }\n } else {\n $scope.course.Media.selectedDevice.selection = $scope.course.AllSyntheticDevices;\n }\n } else {\n $scope.course.SyntheticDevices = $scope.course.AllSyntheticDevices;\n }\n }\n\n function mediaRemoved() {\n return $scope.course.Media.radioModel == \"Simulator\" && !$scope.selectedPhase.InSimulator || $scope.course.Media.radioModel == \"Aircraft\" && !$scope.selectedPhase.InAircraft || $scope.course.Media.radioModel == \"Classroom\" && !$scope.selectedPhase.InClassroom;\n }\n\n function addAircraftRow() {\n var aircraftTypes = $scope.course.AircraftTypes;\n\n if ($scope.course.Media.selectedAircraft.selection != undefined && aircraftTypes && aircraftTypes.includes($scope.course.Media.selectedAircraft.selection) && (!$scope.course.Media.inputAircrafts || !$scope.course.Media.inputAircrafts.includes($scope.course.Media.selectedAircraft.selection))) {\n //Add to selected\n if (!$scope.course.Media.inputAircrafts) {\n $scope.course.Media.inputAircrafts = [];\n }\n\n $scope.course.Media.inputAircrafts.push($scope.course.Media.selectedAircraft.selection); //Remove from options\n\n $scope.course.AircraftTypes = aircraftTypes.filter(function (aircraft) {\n return aircraft != $scope.course.Media.selectedAircraft.selection;\n }); //Clear \n\n $scope.course.Media.selectedAircraft.selection = undefined;\n }\n }\n\n function removeAircraftRow(aircraft) {\n //Remove from selected\n var acIndex = $scope.course.Media.inputAircrafts.indexOf(aircraft);\n $scope.course.Media.inputAircrafts.splice(acIndex, 1); //Add back to options\n\n $scope.course.AircraftTypes.push(aircraft);\n }\n\n function showDowntimeDuration(showDowntime) {\n if (showDowntime == true) {\n $scope.downtimeDuration.show = true;\n } else {\n $scope.downtimeDuration.show = false;\n }\n }\n\n function clearDowntimeDuration() {\n $scope.downtimeDuration.minutes = null;\n }\n\n ;\n\n function downtimeDurationValueChanged() {\n if ($scope.downtimeDuration.minutes > $scope.sessionDuration) {\n $scope.downtimeDuration.minutes = $scope.sessionDuration;\n }\n\n return $scope.downtimeDuration.minutes;\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: \"views/Training/media.tpl.html\",\n $scope: false,\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('ModuleHistoryCtrl', ModuleHistoryCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ModuleHistoryCtrl\r\n * @description \r\n *\r\n * @ngInject\r\n */\n\n function ModuleHistoryCtrl($scope, $routeParams, TrainingSessionFactory, CourseFactory, FlightSessionFactory, $location) {\n $scope.rightScroll = rightScroll;\n $scope.leftScroll = leftScroll;\n $scope.selectedTrainee = selectedTrainee;\n $scope.selectedSession = selectedSession;\n $scope.gotoCourse = gotoCourse;\n var isGround = false;\n\n if ($routeParams.dutyId) {\n isGround = true;\n var courseId = Number($routeParams.courseId);\n var dutyId = Number($routeParams.dutyId);\n var date = $routeParams.date;\n var phaseId = Number($routeParams.phaseId);\n } else {\n var courseId = Number($routeParams.courseId);\n var dutyNo = Number($routeParams.dutyNo);\n var dutyDay = Number($routeParams.dutyDay);\n var date = $routeParams.date;\n var phaseId = Number($routeParams.phaseId);\n }\n\n CourseFactory.getCourseFromStorage(courseId, function (course) {\n $scope.phase = course.CrewCoursePhases.find(function (x) {\n return x.PhaseId == phaseId;\n });\n $scope.course = course;\n\n if (isGround) {\n TrainingSessionFactory.getSessionTrainees(courseId, date, dutyId, function (trainees) {\n initHistory(trainees);\n });\n } else {\n FlightSessionFactory.getSessionTrainees(courseId, date, dutyNo, dutyDay, function (trainees) {\n initHistory(trainees);\n });\n }\n });\n\n function initHistory(trainees) {\n if (trainees && trainees.length) {\n trainees.forEach(function (trainee) {\n trainee.HistoryPhase = trainee.Phases.find(function (x) {\n return x.PhaseId == phaseId;\n });\n });\n $scope.historyTrainees = setHistoryTrainees(trainees);\n $scope.selectedTraineeBadge = {\n crewId: trainees[0].CrewId,\n traineeSessionId: trainees[0].HistoryPhase.Sessions[0].Id\n };\n $scope.selectedSubmittedSessionBadge = {\n sessionId: trainees[0].HistoryPhase.Sessions[0].SessionId\n };\n }\n }\n\n function setHistoryTrainees(trainees) {\n var historyTrainees = trainees.filter(function (x) {\n return x.HistoryPhase && x.HistoryPhase.Sessions && !x.Session.Absent;\n });\n historyTrainees.forEach(function (trainee) {\n trainee.HistoryPhase.hasSectors = trainee.HistoryPhase.Sessions.some(function (x) {\n return x.Sectors && x.Sectors.length > 0;\n });\n trainee.HistoryPhase.Sessions.forEach(function (session) {\n session.hasDayGrading = session.DayGrading.Comments || session.DayGrading.GradeType != 'NotSet' && session.DayGrading.Grade || session.DayGrading.Competences.length > 0;\n session.hasReleaseGrading = session.ReleaseGrading.Comments || session.ReleaseGrading.GradeType != 'NotSet' && session.ReleaseGrading.Grade || session.ReleaseGrading.Competences.length > 0;\n session.AcTypes = _toConsumableArray(new Set(session.Sectors.map(function (ses) {\n return ses.AcType;\n }))); //GroupBy AcType\n\n session.SectorsByAcType = [];\n session.AcTypes.forEach(function (acType) {\n var group = {\n AcType: acType,\n Sectors: session.Sectors.filter(function (x) {\n return x.AcType == acType;\n })\n };\n session.SectorsByAcType.push(group);\n });\n });\n setTraineeSummary(trainee.HistoryPhase);\n });\n return historyTrainees;\n }\n\n function setTraineeSummary(phase) {\n var sectorSummary = [];\n var totalSectors = 0; //Unique ac types of all sessions\n\n var allAcTypes = [];\n phase.Sessions.forEach(function (session) {\n allAcTypes = allAcTypes.concat(session.AcTypes);\n });\n allAcTypes = _toConsumableArray(new Set(allAcTypes)); //Group by ac type\n\n allAcTypes.forEach(function (acType) {\n var sectors = [];\n phase.Sessions.forEach(function (session) {\n sectors = sectors.concat(session.Sectors.filter(function (x) {\n return x.AcType == acType;\n }));\n });\n var sectorGroup = {\n AcType: acType,\n Sectors: sectors\n };\n totalSectors = totalSectors + sectors.length;\n sectorSummary.push(sectorGroup);\n });\n phase.SectorSummary = sectorSummary;\n phase.TotalSectors = totalSectors;\n }\n\n function selectedTrainee() {\n return function (trainee) {\n var showSession = false;\n\n if (trainee.CrewId === $scope.selectedTraineeBadge.crewId) {\n showSession = true;\n }\n\n return showSession;\n };\n }\n\n function selectedSession() {\n return function (historyTrainee) {\n var showSession = false;\n\n if (historyTrainee.SessionId === $scope.selectedSubmittedSessionBadge.sessionId) {\n showSession = true;\n }\n\n return showSession;\n };\n }\n\n function leftScroll() {\n document.querySelector('.horizontal-scroll').scrollLeft -= 500;\n }\n\n function rightScroll() {\n document.querySelector('.horizontal-scroll').scrollLeft += 500;\n }\n\n function gotoCourse() {\n if (isGround) {\n $location.path('/groundcourse/' + Number($routeParams.courseId) + '/' + Number($routeParams.dutyId) + '/' + $routeParams.date);\n } else {\n $location.path('/flightcourse/' + Number($routeParams.courseId) + '/' + Number($routeParams.dutyNo) + '/' + Number($routeParams.dutyDay) + '/' + $routeParams.date);\n }\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('nonEligibleTrainees', nonEligibleTrainees);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name nonEligibleTrainees\r\n * @restrict E\r\n * @description\r\n * Show trainees that are not eligible for this training session\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */\n\n function nonEligibleTrainees(FlightSessionFactory, $routeParams) {\n function link(scope) {\n scope.categories = setCategories(); //Collect duty trainees\n\n var dutyTrainees = [];\n\n if (scope.groundDuty) {\n scope.groundDuty.Trainees.forEach(function (related) {\n related.CrewMembers.forEach(function (trainee) {\n dutyTrainees.push(trainee);\n });\n });\n } else {\n var date = $routeParams.date;\n var dutyNo = Number($routeParams.dutyNo);\n var dutyDay = Number($routeParams.dutyDay);\n var crewRouteCourse = scope.crewRouteDuty.Courses.find(function (x) {\n return x.CourseId == scope.course.Id && new moment(x.Date).isSame(date);\n });\n var dutyTrainees = FlightSessionFactory.getCrewRouteFlightTrainees(dutyNo, dutyDay, crewRouteCourse.TrainingFlightIds);\n }\n\n if (scope.course && scope.course.CourseTrainees) {\n categorizeTrainee(dutyTrainees);\n }\n\n scope.dutyTrainees = dutyTrainees;\n\n function setCategories() {\n var parallelMessage = \"Trainees may have already completed this module\";\n var sequentialMessage = \"Trainees have either completed this module or are not yet ready to start it\";\n return [{\n title: \"InvalidPhase\",\n msg: scope.course.isParallel ? parallelMessage : sequentialMessage,\n trainees: [],\n all: false\n }, {\n title: \"Submitted\",\n msg: \"Trainees have already been submitted\",\n trainees: [],\n all: false\n }, {\n title: \"RecurrentPeriod\",\n msg: \"Trainees have completed the course earlier\",\n trainees: [],\n all: false\n }, {\n title: \"InvalidRole\",\n msg: \"For this training, flight crew trainees can only be assessed by a flight crew instructor\",\n trainees: [],\n all: false\n }];\n }\n\n function categorizeTrainee(dutyTrainees) {\n var allEligibilityTrainees = scope.course.CourseTrainees.concat(scope.course.NonEligibleTrainees);\n dutyTrainees.forEach(function (dutyTrainee) {\n var courseTrainee = allEligibilityTrainees.find(function (x) {\n return x.CrewId == dutyTrainee.Id;\n });\n\n if (courseTrainee) {\n // if (courseTrainee.ActivePhaseStatus == 'Completed') {\n // scope.categories.find(x => x.title==\"Completed\").trainees.push(dutyTrainee);\n // }\n if (!courseTrainee.EligibilityStatus && courseTrainee.EligibilityDesc == 'AlreadySubmitted') {\n scope.categories.find(function (x) {\n return x.title == \"Submitted\";\n }).trainees.push(dutyTrainee);\n }\n\n if (!courseTrainee.EligibilityStatus && courseTrainee.EligibilityDesc == 'InvalidPhase') {\n scope.categories.find(function (x) {\n return x.title == \"InvalidPhase\";\n }).trainees.push(dutyTrainee);\n }\n\n if (!courseTrainee.EligibilityStatus && courseTrainee.EligibilityDesc == 'CooldownPending') {\n scope.categories.find(function (x) {\n return x.title == \"RecurrentPeriod\";\n }).trainees.push(dutyTrainee);\n }\n\n if (!courseTrainee.EligibilityStatus && courseTrainee.EligibilityDesc == 'InvalidRole') {\n scope.categories.find(function (x) {\n return x.title == \"InvalidRole\";\n }).trainees.push(dutyTrainee);\n }\n }\n });\n var allCategory = scope.categories.find(function (x) {\n return x.trainees.length == dutyTrainees.length;\n }); //all trainees in same category\n\n if (allCategory) {\n allCategory.all = true;\n }\n }\n }\n\n return {\n restrict: 'E',\n terminal: true,\n templateUrl: \"views/Training/non-eligible-trainees.tpl.html\",\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('NotificationModalCtrl', NotificationModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name NotificationModalCtrl\r\n * @description \r\n * Shows Show Signature \r\n * @ngInject\r\n */\n\n function NotificationModalCtrl($scope, $uibModalInstance) {\n $scope.close = close;\n /**\r\n * Close the modal\r\n * @memberof NotificationModalCtrl\r\n */\n\n function close() {\n $uibModalInstance.close($scope.success);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('notifications', notifications);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name notifications\r\n * @restrict E\r\n * @description\r\n * Initialize panel with information messages about session's status and necessary actions\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function notifications($routeParams) {\n function link(scope) {\n var info = {\n msg: \"\",\n border: \"\",\n text: \"\",\n showHistory: false\n };\n var date = $routeParams.date;\n scope.filterSession = filterSession;\n scope.selectSession = selectSession;\n scope.historyAvailable = false;\n scope.additionalTrainingRequested = false;\n scope.underAdditionalTraining = false;\n scope.showReleaseOption = false; //If already submitted : show submitted sessions menu and select first [and no additional training is needed]\n\n if (scope.course.SubmittedSessions && scope.course.SubmittedSessions.length) {\n var submittedDay = scope.course.SubmittedSessions[0].DutyDay;\n var isSame = moment(date).isSame(submittedDay);\n\n if (isSame) {\n scope.course.historyAvailable = true;\n scope.historyAvailable = true;\n scope.selectedSubmittedSession = {\n sessionId: scope.course.SubmittedSessions[0].SessionId\n };\n scope.course.SubmittedSessions.forEach(function (submittedSession) {\n submittedSession.TraineesSessions.forEach(function (traineeSession) {\n scope.additionalTrainingRequested = traineeSession.NeedsAdditionalRequest;\n });\n });\n scope.course.SubmittedSessions.forEach(function (submittedSession) {\n if (submittedSession.TraineesSessions.some(function (x) {\n return x.IsReleased == false && x.NeedsAdditionalRequest == false;\n })) {\n scope.showReleaseOption = true;\n }\n\n ;\n });\n }\n } // 1. Check if session has been already submitted \n\n\n var isCourseComplete = scope.isCourseComplete;\n\n if (isCourseComplete) {\n info = {\n msg: \"Training form already submitted for this day.\",\n border: \"border-left-orange\",\n text: \"text-orange\",\n showHistory: true //show what was submitted in read-only view\n\n };\n } // 2. Check if course is Outdated\n\n\n var isCourseOutdated = scope.isCourseOutdated;\n\n if (isCourseOutdated) {\n info = {\n msg: \"You have an outdated version of this course. Please Refresh Course.\",\n border: \"border-left-orange\",\n text: \"text-orange\",\n showHistory: false\n };\n } // 3. Check if course needs an initial fetch\n\n\n var isCourseLimited = scope.isCourseLimited;\n\n if (isCourseLimited && !isCourseComplete) {\n isCourseLimited = true;\n info = {\n msg: \"You need to perform an initial fetch to receive all available information.\",\n border: \"border-left-blue\",\n text: \"text-blue\",\n showHistory: false\n };\n } // Result\n\n\n scope.info = info;\n /**\r\n * Filter submitted sessions based on selected from the top menu\r\n * @returns if session is currently selected\r\n */\n\n function filterSession() {\n return function (traineeSession) {\n var showSessionTrainees = false;\n\n if (traineeSession.SessionId === scope.selectedSubmittedSession.sessionId) {\n showSessionTrainees = true;\n }\n\n return showSessionTrainees;\n };\n }\n\n function selectSession(sessionId) {\n scope.selectedSubmittedSession.sessionId = sessionId;\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: \"views/Training/notifications.tpl.html\",\n scope: false,\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('releasableModule', releasableModule);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name releasableModule\r\n * @restrict E\r\n * @description\r\n * Implementation of releasable Module\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function releasableModule(TrainingSessionFactory, $uibModal, $location) {\n function link(scope) {\n scope.Submit = Submit;\n scope.selectedTrainee = selectedTrainee;\n scope.toggleTrainee = toggleTrainee;\n scope.getRemainingCharacters = getRemainingCharacters;\n scope.leftScroll = leftScroll;\n scope.rightScroll = rightScroll;\n scope.validateGrading = validateGrading;\n scope.getTraineeClass = getTraineeClass;\n scope.openTraineeSignature = openTraineeSignature;\n scope.resetSignature = resetSignature;\n scope.close = close;\n\n var _isGround = scope.groundDuty != null && scope.groundDuty != null;\n\n var phaseId = scope.course.SubmittedSessions[0].PhaseId;\n var phase = scope.course.CrewCoursePhases.find(function (x) {\n return x.PhaseId == phaseId;\n });\n scope.settings = phase.ReleaseGrading; //Collect all trainee sessions that could be released\n\n var trainees = [];\n scope.course.SubmittedSessions.forEach(function (session) {\n session.TraineesSessions.filter(function (x) {\n return x.CouldBeReleased && !x.NeedsAdditionalRequest && !x.UnderAdditionalTraining && !x.IsStoppedTraineeCourse;\n }).forEach(function (traineeSession) {\n traineeSession.RadioModel = true; //set default realease option true\n\n trainees.push(traineeSession);\n });\n });\n\n if (trainees.length) {\n initializeTrainees(trainees, phase);\n }\n\n scope.phase = phase;\n scope.trainees = trainees;\n\n function initializeTrainees(trainees, phase) {\n scope.selectedTraineeBadge = {\n crewId: trainees[0].CrewId\n }; // Set Release Grading\n\n var releaseCompetences = phase.ReleaseGrading.Competences;\n releaseCompetences.forEach(function (competence) {\n competence.MandatorySub = setSubCompetenceValues(competence.MandatorySubCompetences);\n competence.OptionalSub = setSubCompetenceValues(competence.OptionalSubCompetences); //Filter out from optional the ones common with mandatory\n\n competence.OptionalSub = competence.OptionalSub.filter(function (c) {\n return !competence.MandatorySub.includes(c);\n });\n }); //Set Trainee Competences\n\n trainees.forEach(function (traineeSession) {\n var competences = [];\n releaseCompetences.forEach(function (competence) {\n competences.push(JSON.parse(JSON.stringify(competence)));\n });\n traineeSession.ReleaseGrading.Competences = competences;\n }); //Initialize validation\n\n trainees.forEach(function (traineeSession) {\n traineeSession.ReleaseGrading.isGradeValid = scope.settings.GradeType == \"NotSet\";\n traineeSession.ReleaseGrading.isReleaseGradingValid = scope.settings.Competences.length == 0;\n }); //For ground: check aircraft visits\n\n if (_isGround && phase.AircraftTypes.length) {\n trainees.forEach(function (trainee) {\n var visitedAircrafts = trainee.AllVisitedAcTypes;\n var pendingAircrafts = [];\n phase.AircraftTypes.forEach(function (type) {\n var array = type.split(','); //if arvi requirement is not met\n\n if (!array.some(function (x) {\n return visitedAircrafts.includes(x);\n })) {\n var pendingArviList = [];\n\n if (array.length > 1) {\n array.forEach(function (arvi) {\n pendingArviList.push(arvi);\n });\n } else {\n pendingArviList.push(array[0]);\n }\n\n pendingAircrafts.push(pendingArviList);\n }\n });\n trainee.pendingAircrafts = pendingAircrafts;\n trainee.ShowReleaseWarning = trainee.pendingAircrafts.length > 0;\n });\n }\n\n scope.showReleaseWarning = trainees.some(function (x) {\n return x.ShowReleaseWarning;\n });\n }\n\n function selectedTrainee() {\n return function (trainee) {\n var showTrainee = false;\n\n if (trainee.CrewId === scope.selectedTraineeBadge.crewId) {\n showTrainee = true;\n }\n\n return showTrainee;\n };\n }\n\n function close() {\n scope.modalInstance.close();\n }\n\n function toggleTrainee() {\n if (!scope.selectedTraineeBadge.crewId) {\n scope.selectedTraineeBadge.crewId = scope.trainees.find(function (x) {\n return x.RadioModel;\n }).CrewId;\n }\n\n var selectedCrewId = scope.selectedTraineeBadge.crewId;\n var selectedTrainee = scope.trainees.find(function (x) {\n return x.CrewId == selectedCrewId;\n });\n\n if (selectedTrainee && !selectedTrainee.RadioModel) {\n if (scope.trainees.find(function (x) {\n return x.RadioModel;\n })) {\n scope.selectedTraineeBadge.crewId = scope.trainees.find(function (x) {\n return x.RadioModel;\n }).CrewId;\n } else {\n scope.selectedTraineeBadge.crewId = null;\n }\n }\n }\n\n function getTraineeClass(crewId) {\n var textClass = \"\";\n var trainee = scope.trainees.find(function (x) {\n return x.CrewId == crewId;\n }); //Validate Release grading\n\n var isReleaseGradingValid = trainee.ReleaseGrading.isGradeValid;\n var isReleaseCompetencesValid = trainee.ReleaseGrading.isCompetenceValid;\n\n if (isReleaseGradingValid && isReleaseCompetencesValid) {\n textClass = \"bg-green text-white\";\n } else {\n textClass = \"bg-amber text-white\";\n }\n\n return textClass;\n }\n\n function Submit() {\n if (!isValidForm()) {\n scope.modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgSubmitValidation.html',\n scope: scope,\n backdrop: 'static',\n keyboard: false,\n size: 'lg'\n });\n } else {\n scope.modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgSign.html',\n controller: 'ReleaseSignatureModalCtrl',\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n courseId: function courseId() {\n return scope.course.Id;\n },\n isGround: function isGround() {\n return _isGround;\n },\n confirmationMsg: function confirmationMsg() {\n return scope.settings.ConfirmationMessage;\n },\n requiresInstructorSignature: function requiresInstructorSignature() {\n return scope.settings.InstructorSignature;\n },\n trainees: function trainees() {\n return scope.trainees.filter(function (x) {\n return x.RadioModel;\n });\n },\n submitRelease: function submitRelease() {\n return SubmitRelease;\n }\n }\n });\n scope.modalInstance.result.then(function (result) {\n if (result.success) {\n $location.path(\"/\");\n }\n });\n }\n }\n\n function SubmitRelease(password) {\n var submittedSessions = {\n SignaturePassword: password,\n TraineesSessions: trainees.filter(function (x) {\n return x.RadioModel;\n })\n };\n return TrainingSessionFactory.releaseSession(submittedSessions);\n }\n\n function validateGrading(trainee) {\n trainee.ReleaseGrading.isGradeValid = trainee.ReleaseGrading.Grade != null && trainee.ReleaseGrading.Grade != undefined;\n }\n /**\r\n * Calculate remaining characters for comment input\r\n * @param {string} text \r\n * @param {number} max \r\n */\n\n\n function getRemainingCharacters(text, max) {\n if (typeof text === \"undefined\" || text === null) return '';\n if (typeof max === \"undefined\" || max === null || max < 0 || !max) max = 4000;\n var length = text.length;\n return 'characters left: ' + (max - length);\n }\n\n function setSubCompetenceValues(current) {\n var updated = [];\n var first = parseInt(current[0], 10);\n var last = current[current.length - 1];\n\n if (first) {\n for (var i = first; i <= last; i++) {\n updated.push(i);\n }\n }\n\n return updated;\n }\n\n function leftScroll() {\n document.querySelector('.horizontal-scroll').scrollLeft -= 500;\n }\n\n function rightScroll() {\n document.querySelector('.horizontal-scroll').scrollLeft += 500;\n }\n\n function isValidForm() {\n /*Requirements before split release\r\n 1. OnLine Mode\r\n 2. Valid Release Grading\r\n 3. Trainee Signature\r\n */\n var selectedTrainee = scope.trainees.find(function (x) {\n return x.CrewId == scope.selectedTraineeBadge.crewId;\n });\n var isValid = false;\n var info = {\n border: \"\",\n icon: \"\",\n msg: \"\"\n };\n\n if (!window.navigator.onLine) {\n info = {\n border: \"border-left-red\",\n icon: \"fa-warning text-red\",\n msg: \" Online mode is required in order to submit a training.

Check your connection and try again!

\"\n };\n } else if (scope.settings.TraineeSignature && scope.trainees.filter(function (x) {\n return x.RadioModel;\n }).some(function (x) {\n return !x.Authorized;\n })) {\n if (selectedTrainee && !selectedTrainee.Authorized) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-pencil-square-o text-orange\",\n msg: \"\" + selectedTrainee.TraineeName + \" needs to sign the form!\",\n scrollToTop: false\n };\n } else {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"All trainees need to sign their forms!\",\n scrollToTop: true\n };\n }\n } else if (!isGradingValid()) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"\"\n };\n\n if (selectedTrainee && !selectedTrainee.ReleaseGrading.isCompetenceValid) {\n info.msg = \"You need to grade all competences for \" + selectedTrainee.TraineeName + \" before submitting!\";\n } else if (selectedTrainee && !selectedTrainee.ReleaseGrading.isGradeValid) {\n info.msg = \"You need to grade \" + selectedTrainee.TraineeName + \" before submitting!\";\n } else if (!scope.gradingValidationInfo.isReleaseCompetencesValid || !scope.gradingValidationInfo.isReleaseGradingValid) {\n info.msg = \"You need to grade all trainees before submitting!\";\n }\n } else {\n isValid = true;\n }\n\n scope.info = info;\n return isValid;\n }\n\n function validateTraineeForm(trainee) {\n /*Requirements before trainee signature\r\n 1. OnLine Mode\r\n 2. Valid Trainee Release Grading\r\n */\n var isValid = false;\n var info = {\n border: \"\",\n icon: \"\",\n msg: \"\"\n };\n\n if (!window.navigator.onLine) {\n info = {\n border: \"border-left-red\",\n icon: \"fa-warning text-red\",\n msg: \" Online mode is required in order to submit a training.

Check your connection and try again!

\"\n };\n } else if (!trainee.ReleaseGrading.isCompetenceValid) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"You need to grade all competences!\"\n };\n } else if (!trainee.ReleaseGrading.isGradeValid) {\n info = {\n border: \"border-left-orange\",\n icon: \"fa-warning text-orange\",\n msg: \"You need to select an overall grade!\"\n };\n } else {\n isValid = true;\n }\n\n scope.info = info;\n return isValid;\n }\n\n function isGradingValid() {\n var isReleaseGradingValid = scope.settings.GradeType == \"NotSet\";\n var isReleaseCompetencesValid = scope.settings.Competences.length == 0;\n if (!isReleaseGradingValid) isReleaseGradingValid = !scope.trainees.filter(function (x) {\n return x.RadioModel;\n }).some(function (x) {\n return !x.ReleaseGrading.isGradeValid;\n });\n if (!isReleaseCompetencesValid) isReleaseCompetencesValid = !scope.trainees.filter(function (x) {\n return x.RadioModel;\n }).some(function (x) {\n return !x.ReleaseGrading.isCompetenceValid;\n });\n scope.gradingValidationInfo = {\n isReleaseGradingValid: isReleaseGradingValid,\n isReleaseCompetencesValid: isReleaseCompetencesValid\n };\n return isReleaseGradingValid && isReleaseCompetencesValid;\n }\n\n function openTraineeSignature(_trainee) {\n //Enter signature mode : trainee form becomes read-only\n if (!_trainee.Authorized) {\n //Trainee can sign only if his form is valid\n if (!validateTraineeForm(_trainee)) {\n scope.modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgSubmitValidation.html',\n scope: scope,\n backdrop: 'static',\n keyboard: false,\n size: 'lg'\n });\n } else {\n _trainee.Session = {\n Authorized: false\n };\n _trainee.Name = _trainee.TraineeName;\n scope.modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgTraineeSignature.html',\n controller: 'TraineeSignatureModalCtrl',\n scope: scope,\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n trainee: function trainee() {\n return _trainee;\n },\n signatureSuccess: function signatureSuccess() {\n return function () {\n _trainee.Authorized = true;\n };\n }\n }\n });\n }\n }\n }\n\n function resetSignature(_trainee2) {\n var modalInstance = $uibModal.open({\n templateUrl: 'views/Training/dlgResetSignature.html',\n controller: 'TraineeSignatureModalCtrl',\n scope: scope,\n backdrop: 'static',\n keyboard: false,\n size: 'md',\n resolve: {\n trainee: function trainee() {\n return _trainee2;\n },\n signatureSuccess: function signatureSuccess() {\n return function () {};\n }\n }\n });\n modalInstance.result.then(function (confirm) {\n if (confirm) {\n _trainee2.Authorized = false;\n _trainee2.Session.Authorized = false;\n }\n });\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/Training/releasable-module.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('releaseWarning', releaseWarning);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name releaseWarning\r\n * @restrict E\r\n * @description\r\n * Soft rules alert in release\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function releaseWarning() {\n function link(scope, attrs) {\n scope.filterSelectedTrainee = filterSelectedTrainee;\n scope.warningTrainees = scope.trainees.filter(function (x) {\n return !x.Session.Absent && x.ShowReleaseWarning;\n });\n\n function filterSelectedTrainee() {\n return function (trainee) {\n var showTrainee = false;\n\n if (scope.selectedTrainee) {\n showTrainee = trainee.CrewId == scope.selectedTrainee.CrewId;\n }\n\n return showTrainee;\n };\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: \"views/Training/releaseWarning.tpl.html\",\n scope: false,\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('ReleaseSignatureModalCtrl', ReleaseSignatureModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SignatureModalCtrl\r\n * @description \r\n * Shows Show Signature \r\n * @ngInject\r\n */\n\n function ReleaseSignatureModalCtrl($scope, $routeParams, CourseFactory, $uibModalInstance, courseId, isGround, confirmationMsg, requiresInstructorSignature, trainees, submitRelease) {\n $scope.close = close;\n $scope.submit = submit;\n $scope.confirm = confirm;\n $scope.confirmAircraft = confirmAircraft;\n $scope.errorMessage = \"\";\n $scope.successMessage = \"\";\n $scope.responseText = null;\n $scope.responseHasErrors = null;\n $scope.success = false;\n $scope.isLoading = false;\n $scope.formData = {};\n $scope.requiredSignature = requiresInstructorSignature;\n $scope.isConfirmed = true;\n $scope.finalPendigArVis = [];\n\n if (isGround && hasPendingAircraftVisits()) {\n $scope.aircraftVisits = true;\n } else if (confirmationMsg) {\n $scope.confirmationMsg = confirmationMsg;\n $scope.isConfirmed = false;\n } else {\n if (!requiresInstructorSignature) {\n //if signature isn't required continue with submit \n $scope.isLoading = true;\n submit();\n }\n }\n\n function hasPendingAircraftVisits() {\n var released = trainees.filter(function (x) {\n return x.RadioModel;\n });\n var pendingVisits = released.some(function (x) {\n return x.pendingAircrafts && x.pendingAircrafts.length > 0;\n });\n\n if (pendingVisits) {\n var maxLength = 0;\n released.forEach(function (trainee) {\n if (trainee.pendingAircrafts.length > maxLength) {\n var maxList = trainee.pendingAircrafts;\n maxLength = maxList.length;\n $scope.finalPendigArVis = trainee.pendingAircrafts;\n }\n });\n }\n\n return pendingVisits;\n }\n\n function confirm() {\n $scope.isConfirmed = true;\n\n if (!requiresInstructorSignature) {\n //if signature isn't required continue with submit \n $scope.isLoading = true;\n submit();\n }\n }\n\n function confirmAircraft() {\n $scope.aircraftVisits = false;\n\n if (confirmationMsg) {\n $scope.confirmationMsg = confirmationMsg;\n $scope.isConfirmed = false;\n }\n }\n\n function submit() {\n $scope.errorMessage = \"\";\n $scope.successMessage = \"\";\n $scope.isLoading = true;\n $scope.success = false;\n var signaturePassword = $scope.formData.password;\n\n if (!signaturePassword && requiresInstructorSignature) {\n $scope.isLoading = false;\n $scope.errorMessage = \"Signature is required. Please enter your password.\";\n } else {\n submitRelease(signaturePassword).then(function (data) {\n $scope.isLoading = false;\n var errorMessage = data.data.errorMessage;\n $scope.successMessage = \"Training has been submitted.\"; //always show errorMessage even if success is true\n\n if (errorMessage && errorMessage.length > 0) {\n $scope.errorMessage = errorMessage; //not Release Trainees\n\n var responseTrainees = data.data.data.data;\n var responseTraineeCrewIds = responseTrainees.map(function (trainee) {\n return trainee.CrewId;\n });\n $scope.traineeInfo = trainees.filter(function (x) {\n return responseTraineeCrewIds.includes(x.CrewId);\n });\n } else {\n $scope.errorMessage = null;\n }\n\n CourseFactory.setCourseOutdated(courseId);\n $scope.success = true;\n })[\"catch\"](function (data) {\n $scope.isLoading = false;\n\n if (data.data && data.data.errorMessage) {\n $scope.errorMessage = data.data.errorMessage;\n } else {\n $scope.errorMessage = \"Failed to save Training Session\";\n }\n });\n } // clear password\n\n\n $scope.formData.password = \"\";\n }\n /**\r\n * Close the modal\r\n * @memberof SignModalCtrl\r\n */\n\n\n function close() {\n var result = {\n \"success\": $scope.success\n };\n $uibModalInstance.close(result);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('SignatureModalCtrl', SignatureModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SignatureModalCtrl\r\n * @description \r\n * Shows Show Signature \r\n * @ngInject\r\n */\n\n function SignatureModalCtrl($scope, $routeParams, $uibModalInstance, TrainingSessionFactory, FlightSessionFactory, GroundDutyFactory, CrewRouteFactory, CourseFactory, courseId, date, dutyId, dutyNo, dutyDay, confirmationMsg, requiresInstructorSignature, trainees, submitSession, releaseGrading, isReleased, needsAdditionalTraining) {\n $scope.close = close;\n $scope.submit = submit;\n $scope.confirm = confirm;\n $scope.confirmSubmit = confirmSubmit;\n $scope.releaseSubmit = releaseSubmit;\n $scope.confirmAircraft = confirmAircraft;\n $scope.errorMessage = \"\";\n $scope.successMessage = \"\";\n $scope.responseText = null;\n $scope.responseHasErrors = null;\n $scope.success = false;\n $scope.isLoading = false;\n $scope.withGrading = false;\n $scope.formData = {};\n var requiredSignature = requiresInstructorSignature;\n $scope.requiredSignature = requiredSignature;\n $scope.releaseWarning = false;\n $scope.isConfirmed = true;\n $scope.releaseGrading = releaseGrading;\n $scope.finalPendigArVis = [];\n $scope.needsAdditionalTraining = needsAdditionalTraining;\n var isGroundDuty = false;\n\n if (dutyId) {\n isGroundDuty = true;\n }\n\n if (releaseNotSelected()) {\n $scope.releaseWarning = true;\n } else if (isGroundDuty && hasPendingAircraftVisits()) {\n $scope.aircraftVisits = true;\n } else if (confirmationMsg && isReleased) {\n $scope.confirmationMsg = confirmationMsg;\n $scope.isConfirmed = false;\n } else {\n if (!requiresInstructorSignature) {\n //if signature isn't required continue with submit \n $scope.isLoading = true;\n submit();\n }\n }\n\n function releaseNotSelected() {\n var allAvailable = !trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.AvailableRelease;\n });\n var notReleased = trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.Session.Released;\n });\n return allAvailable && notReleased;\n }\n\n function hasPendingAircraftVisits() {\n var released = !trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return !x.Session.Released;\n }) || $scope.withGrading;\n var pendingVisits = released && trainees.filter(function (x) {\n return !x.Session.Absent;\n }).some(function (x) {\n return x.pendingAircrafts && x.pendingAircrafts.length > 0;\n });\n\n if (pendingVisits) {\n var maxLength = 0;\n trainees.filter(function (x) {\n return !x.Session.Absent;\n }).forEach(function (trainee) {\n if (trainee.pendingAircrafts.length > maxLength) {\n var maxList = trainee.pendingAircrafts;\n maxLength = maxList.length;\n $scope.finalPendigArVis = trainee.pendingAircrafts;\n }\n });\n }\n\n return pendingVisits;\n }\n\n function confirm() {\n $scope.isConfirmed = true;\n\n if (!requiresInstructorSignature) {\n //if signature isn't required continue with submit \n $scope.isLoading = true;\n submit();\n }\n }\n\n function confirmSubmit() {\n $scope.releaseWarning = false;\n\n if (isGroundDuty && hasPendingAircraftVisits()) {\n $scope.aircraftVisits = true;\n }\n }\n\n function confirmAircraft() {\n $scope.aircraftVisits = false;\n\n if (confirmationMsg) {\n $scope.confirmationMsg = confirmationMsg;\n $scope.isConfirmed = false;\n }\n }\n\n function releaseSubmit() {\n $scope.withGrading = true;\n $scope.releaseWarning = false;\n\n if (hasPendingAircraftVisits()) {\n $scope.aircraftVisits = true;\n } else if (confirmationMsg) {\n $scope.confirmationMsg = confirmationMsg;\n $scope.isConfirmed = false;\n }\n }\n\n function submit() {\n $scope.errorMessage = \"\";\n $scope.successMessage = \"\";\n $scope.isLoading = true;\n $scope.success = false;\n var signaturePassword = $scope.formData.password;\n\n if (!signaturePassword && requiredSignature) {\n $scope.isLoading = false;\n $scope.errorMessage = \"Signature is required. Please enter your password.\";\n } else {\n submitSession(signaturePassword, $scope.withGrading).then(function (data) {\n $scope.isLoading = false;\n var errorMessage = data.data.errorMessage;\n $scope.successMessage = \"Training has been submitted.\"; //always show errorMessage even if success is true\n\n if (errorMessage && errorMessage.length > 0) {\n $scope.errorMessage = errorMessage; //not Release Trainees\n\n var responseTrainees = data.data.data.data;\n var responseTraineeCrewIds = responseTrainees.map(function (trainee) {\n return trainee.CrewId;\n });\n $scope.traineeInfo = trainees.filter(function (x) {\n return responseTraineeCrewIds.includes(x.CrewId);\n });\n } else {\n $scope.errorMessage = null;\n }\n\n if (dutyId) {\n //isGround\n TrainingSessionFactory.remove(courseId, date, dutyId);\n GroundDutyFactory.setCourseCompleted(dutyId, courseId);\n } else {\n //isFlight\n FlightSessionFactory.remove(courseId, date, dutyNo, dutyDay);\n CrewRouteFactory.setCourseCompleted(dutyNo, dutyDay, courseId, date);\n }\n\n CourseFactory.setCourseOutdated(courseId);\n $scope.success = true;\n })[\"catch\"](function (data) {\n $scope.isLoading = false;\n\n if (data.data && data.data.errorMessage) {\n $scope.errorMessage = data.data.errorMessage;\n } else {\n $scope.errorMessage = \"Failed to save Training Session\";\n }\n });\n } // clear password\n\n\n $scope.formData.password = \"\";\n }\n /**\r\n * Close the modal\r\n * @memberof SignModalCtrl\r\n */\n\n\n function close() {\n var result = {\n \"success\": $scope.success\n };\n $uibModalInstance.close(result);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('syllabusItemHeader', syllabusItemHeader);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name syllabusItemHeader\r\n * @restrict E\r\n * @description\r\n * Panel heading for syllabus items\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function syllabusItemHeader() {\n function link(scope, element, attrs) {\n scope.selectTry = selectTry;\n scope.selectGrading = selectGrading; //find first not ReadOnly try\n\n scope.pendingAttempt = scope.item.Tries.find(function (x) {\n return x.isFirstTry;\n });\n scope.firstTry = scope.item.Tries[0];\n\n function selectTry() {\n if (scope.pendingAttempt) {\n scope.itemSelection();\n }\n }\n\n function selectGrading() {\n scope.gradingSelection();\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/Training/syllabus-item-header.tpl.html',\n scope: {\n item: \"=\",\n itemSelection: \"&onItemSelection\",\n gradingSelection: \"&onGradingSelection\"\n },\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('syllabus', syllabus);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name certificates\r\n * @restrict E\r\n * @description\r\n * Implementation of syllabus\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function syllabus(TrainingSessionFactory, FlightSessionFactory, $timeout) {\n function link(scope, element, attrs) {\n var isGround = false;\n var courseId = scope.dutyCourse.Id;\n\n if (scope.groundDuty) {\n isGround = true;\n var date = scope.groundDuty.DutyDateS;\n var dutyId = scope.groundDuty.Id;\n } else {\n var date = scope.crewRouteDuty.date;\n var dutyNo = scope.crewRouteDuty.DutyNo;\n var dutyDay = scope.crewRouteDuty.DutyDay;\n }\n\n scope.updateTraineesSyllabus = updateTraineesSyllabus;\n scope.selectTry = selectTry;\n scope.updateTry = updateTry;\n scope.oneAtATime = true;\n scope.addTry = addTry;\n scope.removeTry = removeTry;\n scope.setPanelStyle = setPanelStyle;\n scope.selectTryFromHeader = selectTryFromHeader;\n scope.gradeFromHeader = gradeFromHeader;\n scope.nonGradableSyllabus = scope.traineeSyllabi[0].Items.every(function (item) {\n return !item.IsGradable;\n });\n scope.personalizedRemarks = false;\n scope.showPersonalizedRemarks = false;\n scope.personalizedRemarksChanged = personalizedRemarksChanged;\n scope.addTraineeRemarksRow = addTraineeRemarksRow;\n scope.traineesPersonalizedRemarks = [];\n scope.updatePersonalizeRemarks = updatePersonalizeRemarks;\n scope.deleteTraineeRemarks = deleteTraineeRemarks;\n scope.isAddRemarksButtonDisabled = isAddRemarksButtonDisabled;\n scope.traineeValueChanged = traineeValueChanged;\n scope.hasSelectedTrainee = false;\n scope.traineeSyllabi.forEach(function (traineeSyllabus) {\n traineeSyllabus.Items.forEach(function (syllabusItem) {\n syllabusItem.usePersonalizedRemarks = false;\n syllabusItem.traineesPersonalizedRemarks = [];\n syllabusItem.Tries.forEach(function (attempt) {\n //Check if default grade exists & set status\n if (syllabusItem.IsGradable && !attempt.isReadOnly) {\n itemAutoSelection(syllabusItem, attempt); //select item depending on grade existence\n }\n });\n setPanelStyle(syllabusItem); //ui depending on validation & status\n\n updateTraineesSyllabus(syllabusItem, traineeSyllabus); //copy values to all trainee syllabi \n });\n }); //Multiple syllabi - Get session to store competence grading\n\n if (scope.traineeSyllabi.length > 1) {\n scope.traineeSyllabi.forEach(function (traineeSyllabus) {\n var crewId = traineeSyllabus.TraineeIds[0];\n var trainee = scope.trainees.find(function (x) {\n return x.CrewId == crewId;\n });\n traineeSyllabus.TraineeName = trainee.Name;\n traineeSyllabus.TraineeAimsId = trainee.AimsId;\n });\n }\n\n function gradeFromHeader(syllabus, syllabusItem) {\n var firstPendingTry = syllabusItem.Tries.filter(function (x) {\n return !x.isReadOnly;\n })[0];\n updateTry(syllabus, syllabusItem, firstPendingTry);\n setPanelStyle(syllabusItem);\n updateTraineesSyllabus(syllabusItem, syllabus);\n triggerSyllabusClick();\n }\n\n function selectTryFromHeader(syllabus, syllabusItem) {\n var firstPendingTry = syllabusItem.Tries.filter(function (x) {\n return !x.isReadOnly;\n })[0];\n selectTry(syllabus, syllabusItem, firstPendingTry);\n\n if (isGround) {\n TrainingSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyId, console.log, function (e) {\n console.log(e);\n });\n } else {\n FlightSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyNo, dutyDay, console.log, function (e) {\n console.log(e);\n });\n }\n\n triggerSyllabusClick();\n }\n\n function triggerSyllabusClick() {\n //preventDefault() and stopPropagation() prevents setReleaseStatus() to be triggered\n $timeout(function () {\n var el = document.getElementById('syllabus');\n angular.element(el).triggerHandler('click');\n }, 0);\n }\n\n function selectTry(syllabus, syllabusItem, attempt) {\n attempt.Selected = !attempt.Selected;\n syllabusItem.Selected = syllabusItem.Tries.filter(function (t) {\n return !t.isReadOnly;\n }).some(function (t) {\n return t.Selected;\n });\n setPanelStyle(syllabusItem);\n updateTraineesSyllabus(syllabusItem, syllabus);\n }\n\n function updateTry(syllabus, syllabusItem, attempt) {\n if (syllabusItem.IsGradable) {\n itemAutoSelection(syllabusItem, attempt); //select item depending on grade existence\n }\n\n setPanelStyle(syllabusItem); //ui depending on validation & status\n\n updateTraineesSyllabus(syllabusItem, syllabus); //copy values to all trainee syllabi \n\n updateSession(); //save in IndexDb\n }\n\n function itemAutoSelection(syllabusItem, attempt) {\n var hasCompetencesGrading = attempt.TryGrading.Competences.some(function (x) {\n return x.Grading;\n });\n\n if (attempt.TryGrading.Grade || hasCompetencesGrading) {\n attempt.Selected = true;\n syllabusItem.Selected = true;\n } else {\n attempt.Selected = false;\n syllabusItem.Selected = false; //Check if any of the tries has grading - If not, deselect item\n\n var pendingTries = syllabusItem.Tries.filter(function (x) {\n return !x.isReadOnly;\n }); //filter out history tries\n\n for (var i = 0; i < pendingTries.length; i++) {\n var itemTry = pendingTries[i];\n var tryCompetenceGrading = itemTry.TryGrading.Competences.some(function (x) {\n return x.Grading;\n });\n\n if (itemTry.TryGrading.Grade || tryCompetenceGrading) {\n syllabusItem.Selected = true;\n break;\n }\n }\n }\n }\n\n function setPanelStyle(item) {\n var historyTriesCount = item.Tries.filter(function (x) {\n return x.isReadOnly;\n }).length;\n var newTriesCount = item.Tries.filter(function (x) {\n return !x.isReadOnly && x.Selected;\n }).length;\n item.TriesPerformedCount = historyTriesCount + newTriesCount;\n var completedItem = item.TriesPerformedCount >= item.MandatoryCount;\n\n if (item.MandatoryCount == 0) {\n //non-mandatory items are considered completed if performed at least once\n completedItem = item.TriesPerformedCount >= 1;\n }\n\n var invalidItem = false;\n var nonCompetentItem = false;\n\n if (item.IsGradable && item.Selected) {\n var gradingType = item.GradeType; //Numeric or Outcome or Competences\n\n var traineeSelectedTries = item.Tries.filter(function (x) {\n return x.Selected;\n });\n traineeSelectedTries.forEach(function (selectedTry) {\n var invalidGrading = gradingType != \"Competences\" && !selectedTry.TryGrading.Grade;\n var invalidCompetences = gradingType == \"Competences\" && !selectedTry.TryGrading.isCompetenceValid;\n\n if (invalidGrading || invalidCompetences) {\n invalidItem = true;\n }\n });\n\n if (!invalidItem && gradingType == \"Outcome\" && item.MandatoryCount > 0) {\n // Get the grades from the tries\n var tries = item.Tries.map(function (t) {\n return t.TryGrading.Grade;\n });\n var mandatoryTries = item.MandatoryCount;\n var competentCount = 0;\n var nonCompetentCount = 0;\n var isCompetent = false;\n\n for (var i = 0; i < tries.length; i++) {\n if (tries[i] === 'Pass') {\n competentCount++;\n nonCompetentCount = 0; // reset non-competent count\n\n if (competentCount >= mandatoryTries) {\n item.PanelClass = 'panel-border-left-green';\n isCompetent = true;\n }\n } else {\n if (tries[i] === 'Fail') {\n nonCompetentCount++;\n competentCount = 0;\n\n if (nonCompetentCount >= mandatoryTries) {\n item.PanelClass = 'panel-border-left-pink';\n nonCompetentItem = true;\n break; // Exit if mandatory fails are reached\n }\n }\n }\n }\n\n if (nonCompetentItem) {\n item.PanelClass = 'panel-border-left-pink';\n } else if (isCompetent) {\n item.PanelClass = 'panel-border-left-green';\n } else {\n item.PanelClass = 'panel-border-left-blue';\n }\n\n return;\n }\n\n if (!invalidItem && gradingType != \"Outcome\" && traineeSelectedTries.some(function (t) {\n return t.TryGrading.Grade === \"Fail\";\n })) {\n nonCompetentItem = true;\n }\n }\n\n if (completedItem && !nonCompetentItem) {\n item.PanelClass = 'panel-green panel-border-left-green ';\n } else if (completedItem && nonCompetentItem) {\n item.PanelClass = 'panel-border-left-pink';\n } else {\n item.PanelClass = 'panel-border-left-blue ';\n }\n\n if (invalidItem) {\n item.PanelClass = 'panel-border-left-orange ';\n }\n }\n\n function updateTraineesSyllabus(item, syllabus) {\n var crewIds = syllabus.TraineeIds;\n scope.trainees.filter(function (x) {\n return crewIds.includes(x.CrewId);\n }).forEach(function (trainee) {\n var sessionItem = trainee.Session.Items.find(function (sessionItem) {\n return item.Id == sessionItem.Id;\n });\n sessionItem.RepeatRequired = item.RepeatRequired;\n sessionItem.Selected = item.Selected;\n sessionItem.PhaseId = item.PhaseId;\n sessionItem.Tries = deepCopy(item.Tries);\n sessionItem.SyllabusItemId = item.Id;\n sessionItem.TriesPerformedCount = item.TriesPerformedCount;\n });\n updatePersonalizeRemarks(item);\n }\n\n function deepCopy(originalObject) {\n return JSON.parse(JSON.stringify(originalObject));\n }\n\n function addTry(item, syllabus) {\n var competences = deepCopy(item.Competences);\n var newTry = {\n Comments: null,\n ActionNo: item.Tries.length + 1,\n Selected: true,\n TryGrading: {\n Grade: null,\n Competences: competences,\n GradeType: item.GradeType\n }\n };\n item.Selected = true;\n item.Tries.push(newTry);\n setPanelStyle(item);\n updateTraineesSyllabus(item, syllabus);\n }\n\n function removeTry(item, syllabus) {\n item.Tries.pop();\n\n if (!item.Tries.filter(function (x) {\n return !x.isReadOnly;\n }).length) {\n item.Selected = false;\n }\n\n setPanelStyle(item);\n updateTraineesSyllabus(item, syllabus);\n }\n\n function updateSession() {\n if (isGround) {\n TrainingSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyId, console.log, function (e) {\n console.log(e);\n });\n } else {\n FlightSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyNo, dutyDay, console.log, function (e) {\n console.log(e);\n });\n }\n } // if syllabus is non-gradable instructor can add persomalized trainee remarks\n\n\n function addTraineeRemarksRow(syllabusItem, selectedTraineeId) {\n if (selectedTraineeId) {\n var selectedTrainee = scope.trainees.find(function (trainee) {\n return trainee.CrewId == selectedTraineeId;\n });\n\n if (selectedTrainee) {\n scope.selectedTraineeName = selectedTrainee.Name;\n var newTraineeRemarks = {\n id: selectedTrainee.CrewId,\n name: selectedTrainee.Name,\n remarks: \"\",\n // Add an empty remarks field for the new trainee\n syllabusItemId: syllabusItem.Id\n };\n syllabusItem.selectedTrainee = newTraineeRemarks;\n syllabusItem.traineesPersonalizedRemarks.push(newTraineeRemarks);\n }\n }\n }\n\n scope.getAvailableTrainees = function (allTrainees, item) {\n if (!item || !item.traineesPersonalizedRemarks) {\n return allTrainees;\n } // Get the IDs of already selected trainees\n\n\n var selectedTraineeIds = item.traineesPersonalizedRemarks.map(function (remark) {\n return remark.id;\n }); // Filter out the selected trainees\n\n return allTrainees.filter(function (trainee) {\n return !selectedTraineeIds.includes(trainee.CrewId);\n });\n };\n\n function personalizedRemarksChanged(item) {\n if (item.usePersonalizedRemarks) {\n item.showPersonalizedRemarks = true;\n item.Tries.forEach(function (itemTry) {\n itemTry.Comments = \"\"; // Clear comments when enabling personalized remarks\n });\n } else {\n item.showPersonalizedRemarks = false;\n item.usePersonalizedRemarks = false;\n scope.traineesPersonalizedRemarks = [];\n }\n }\n\n function updatePersonalizeRemarks(item) {\n if (item.traineesPersonalizedRemarks && item.traineesPersonalizedRemarks.length > 0) {\n item.traineesPersonalizedRemarks.forEach(function (personalizedRemark) {\n var trainee = scope.trainees.find(function (x) {\n return x.CrewId == personalizedRemark.id;\n });\n\n if (trainee) {\n var sessionItem = trainee.Session.Items.find(function (item) {\n return item.SyllabusItemId == personalizedRemark.syllabusItemId;\n });\n\n if (sessionItem && sessionItem.Tries.length > 0) {\n sessionItem.Tries[0].Comments = personalizedRemark.remarks;\n }\n }\n });\n }\n }\n\n function deleteTraineeRemarks(traineeRemarks, item) {\n if (item) {\n // Remove the trainee remarks from the array\n var index = item.traineesPersonalizedRemarks.findIndex(function (remarks) {\n return remarks.id === traineeRemarks.id;\n });\n\n if (index !== -1) {\n item.traineesPersonalizedRemarks.splice(index, 1); // After deleting, sync the changes with the Session\n\n updatePersonalizeRemarks(item); // Enable the deleted trainee for the current item\n\n item.selectedTrainee = null;\n } else {\n console.error(\"Trainee remarks not found for deletion.\");\n }\n } else {\n console.error(\"Syllabus item not found for the trainee remarks.\");\n }\n }\n\n function isAddRemarksButtonDisabled(item) {\n return !scope.getAvailableTrainees(scope.trainees, item).length;\n }\n\n ;\n\n function traineeValueChanged(selectedTrainee) {\n if (selectedTrainee) {\n scope.hasSelectedTrainee = true;\n } else {\n scope.hasSelectedTrainee = false;\n }\n }\n }\n\n return {\n restrict: 'E',\n terminal: false,\n templateUrl: 'views/Training/syllabus.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('TraineeSignatureModalCtrl', TraineeSignatureModalCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name TraineeSignatureModalCtrl\r\n * @description \r\n * Shows Show Signature \r\n * @ngInject\r\n */\n\n function TraineeSignatureModalCtrl($scope, $timeout, $uibModalInstance, trainee, TrainingSessionFactory, signatureSuccess) {\n $scope.close = close;\n $scope.confirmReset = confirmReset;\n $scope.traineeSign = traineeSign;\n $scope[\"continue\"] = continueWarning;\n $scope.confirmation = false;\n initialiazeTrainee(trainee);\n\n function initialiazeTrainee(trainee) {\n var signatureTrainee = deepCopy(trainee);\n signatureTrainee.Session.Authorized = trainee.Session.Authorized ? trainee.Session.Authorized : false;\n signatureTrainee.errorMessage = \"\";\n signatureTrainee.successMessage = \"\";\n signatureTrainee.responseText = null;\n signatureTrainee.responseHasErrors = null;\n signatureTrainee.success = false;\n signatureTrainee.isLoading = false;\n signatureTrainee.password = \"\";\n signatureTrainee.username = trainee.AimsId;\n signatureTrainee.PositionCode = trainee.position ? trainee.position : trainee.PositionCode;\n $scope.signatureTrainee = signatureTrainee;\n }\n\n function deepCopy(originalObject) {\n return JSON.parse(JSON.stringify(originalObject));\n }\n\n function traineeSign(signatureTrainee) {\n if (!signatureTrainee.password || !signatureTrainee.username) {\n signatureTrainee.errorMessage = \"Signature is required. Please enter your username and password.\";\n } else {\n signatureTrainee.isLoading = true; //Individually authorize trainee\n\n var credentials = {\n CrewId: signatureTrainee.CrewId,\n Password: signatureTrainee.password,\n Username: signatureTrainee.username,\n PositionCode: signatureTrainee.PositionCode\n };\n\n if ($scope.isOffline) {\n $timeout(function () {\n signatureTrainee.isLoading = false;\n }, 100);\n signatureTrainee.errorMessage = \"Online mode is required in order to sign. Please connect to the internet and try again.\";\n } else {\n TrainingSessionFactory.authorizeTrainee(credentials, function (responseData) {\n signatureTrainee.isLoading = false;\n signatureTrainee.success = true;\n signatureTrainee.Session.Authorized = true;\n trainee.Session.Authorized = true;\n signatureSuccess();\n })[\"catch\"](function (data) {\n signatureTrainee.isLoading = false;\n\n if (data.data && data.data.errorMessage) {\n signatureTrainee.errorMessage = data.data.errorMessage;\n } else {\n signatureTrainee.errorMessage = \"An error occured during your authentication\";\n }\n });\n }\n } // clear credentials\n\n\n trainee.username = \"\";\n trainee.password = \"\";\n }\n /**\r\n * Close the modal\r\n */\n\n\n function close() {\n $uibModalInstance.close(false);\n }\n /**\r\n * Confirm\r\n */\n\n\n function confirmReset() {\n $uibModalInstance.close(true);\n }\n\n function continueWarning() {\n $scope.confirmation = true;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n a3_cabin_reports.directive('trainingMenu', trainingMenu);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name ground Course List\r\n * @restrict E\r\n * @description\r\n * Initialize navigation menu panel with with status indicators\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function trainingMenu(CourseFactory, GroundDutyFactory, FlightFactory, CrewRouteFactory, $location, TrainingSessionFactory, FlightSessionFactory, $filter, $routeParams) {\n function link($scope, attrs) {\n $scope.gotoCourse = gotoCourse;\n $scope.hasPendingTraining = false;\n $scope.hasUnsetTraining = false;\n var groundSessions = [];\n var flightSessions = [];\n TrainingSessionFactory.getAll(function (savedGroundSessions) {\n FlightSessionFactory.getAll(function (savedFlightSessions) {\n groundSessions = savedGroundSessions;\n flightSessions = savedFlightSessions;\n $scope.courses = [];\n var duty = null;\n var dutyCourses = [];\n\n if ($scope.type == 'ground') {\n duty = GroundDutyFactory.getGroundDutyFromStorage($scope.id);\n $scope.duty = duty;\n\n if (duty && duty.RelatedGroundDuties) {\n dutyCourses = GroundDutyFactory.getGroundDutyActiveCourses($scope.id);\n\n if (dutyCourses) {\n CourseFactory.getCoursesFromStorageByIds(dutyCourses.map(function (course) {\n return course.CourseId;\n }), function (savedCourses) {\n manageGroundCourseStatuses(duty, dutyCourses, savedCourses); //Overall panel color\n\n if (savedCourses.some(function (x) {\n return x.Status == \"Draft\";\n })) {\n $scope.PanelClass = \"border-bottom-orange\";\n } else if (savedCourses.some(function (x) {\n return x.Status == \"Pending\" || x.Status == \"Outdated\";\n })) {\n $scope.PanelClass = \"border-bottom-blue\";\n } else {\n $scope.PanelClass = \"border-bottom-green\";\n }\n\n $scope.courses = savedCourses;\n });\n }\n }\n } else if ($scope.type == 'crewroute' || $scope.type == 'flight') {\n if ($scope.type == 'crewroute') {\n duty = CrewRouteFactory.getCrewRouteFromStorage($scope.dutyNo, $scope.dutyDay);\n } else {\n duty = FlightFactory.getFlightFromTotalFlights($scope.id);\n }\n\n if (duty && duty.Courses) {\n dutyCourses = duty.Courses;\n CourseFactory.getCoursesFromStorageByIds(dutyCourses.map(function (course) {\n return course.CourseId;\n }), function (savedCourses) {\n dutyCourses.forEach(function (dutyCourse) {\n var savedCourse = savedCourses.find(function (x) {\n return x.Id == dutyCourse.CourseId;\n });\n\n if (savedCourse) {\n var course = {\n Id: savedCourse.Id,\n Title: savedCourse.Title,\n Day: new moment(dutyCourse.Date)\n };\n manageFlightCourseStatus(course, dutyCourse);\n $scope.courses.push(course);\n }\n });\n $scope.courses.forEach(function (course) {\n course.FullDate = course.Day.format(\"YYYY-MM-DD\");\n course.Day = course.Day.format(\"DD/MM\");\n\n if ($scope.courses.filter(function (x) {\n return x.Id == course.Id;\n }).length > 1) {\n course.IsMultiday = true;\n }\n }); //Overall panel color\n\n if ($scope.courses.some(function (x) {\n return x.Status == \"Draft\";\n })) {\n $scope.PanelClass = \"border-bottom-orange\";\n } else if ($scope.courses.some(function (x) {\n return x.Status == \"Pending\" || x.Status == \"Outdated\";\n })) {\n $scope.PanelClass = \"border-bottom-blue\";\n } else {\n $scope.PanelClass = \"border-bottom-green\";\n }\n });\n }\n }\n });\n });\n\n function manageFlightCourseStatus(course, crewRouteCourse) {\n var now = moment.utc();\n var flights = FlightFactory.getFlightsFromStorage().filter(function (x) {\n return crewRouteCourse.TrainingFlightIds.includes(x.FlightId);\n });\n flights = $filter('orderBy')(flights, 'ScheduledArrival');\n var dutyEnd = flights[flights.length - 1].ScheduledArrival;\n var dutyDate = new moment(crewRouteCourse.Date).format(\"YYYY-MM-DD\");\n var status = \"\";\n\n if (crewRouteCourse.Status == \"Pending\") {\n //Pending\n course.Status = \"Pending\";\n course.StatusClass = \"text-blue\";\n course.StatusDesc = \"pending\"; //Outdated\n\n dutyEnd = moment.utc(dutyEnd);\n var duration = moment.duration(now.diff(dutyEnd)).asHours();\n\n if (duration > 1) {\n course.Status = \"Outdated\";\n } //Draft\n\n\n if (flightSessions && flightSessions.length > 0) {\n var existingSession = flightSessions.find(function (s) {\n return s != null && s.courseId == crewRouteCourse.CourseId && s.day == dutyDate && s.dutyDay == $scope.dutyDay && s.dutyNo == $scope.dutyNo;\n });\n\n if (existingSession && !existingSession.HasLimitedInfo && existingSession.trainees && existingSession.trainees.length) {\n //a training session with trainees exists\n course.Status = \"Draft\";\n course.StatusClass = \"text-orange\";\n course.StatusDesc = \"draft\";\n }\n }\n } else if (crewRouteCourse.Status == \"Completed\") {\n //Completed\n course.Status = \"Completed\";\n course.StatusClass = \"text-green\";\n course.StatusDesc = \"synced\";\n }\n\n return status;\n }\n\n function manageGroundCourseStatuses(duty, dutyCourses, courses) {\n var now = moment.utc();\n courses.forEach(function (course) {\n var dutyCourse = dutyCourses.find(function (x) {\n return x.CourseId == course.Id;\n });\n course.Status = dutyCourse.Status;\n /*Statuses\r\n \tCompleted : session has been sent\r\n \tOutdated :\tsession submission is overdue\r\n \tDraft\t : session completion has started but not submitted\r\n \tPending : session submission not yet due\r\n */\n\n if (course.Status == \"Pending\") {\n course.StatusClass = \"text-blue\";\n course.StatusDesc = \"pending\"; //Outdated\n\n var dutyEnd = moment.utc(duty.DutyEnd);\n var duration = moment.duration(now.diff(dutyEnd)).asHours();\n\n if (duration > 1) {\n course.Status = \"Outdated\";\n } //Draft\n\n\n if (groundSessions && groundSessions.length) {\n var existingSession = groundSessions.find(function (s) {\n return s.courseId == course.Id && s.day == duty.DutyDateS && s.dutyId == duty.Id;\n });\n\n if (existingSession && !existingSession.HasLimitedInfo && existingSession.trainees && existingSession.trainees.length) {\n //a training session with trainees exists\n course.Status = \"Draft\";\n course.StatusClass = \"text-orange\";\n course.StatusDesc = \"draft\";\n }\n }\n } else if (course.Status == \"Completed\") {\n //Completed\n course.Status = \"Completed\";\n course.StatusClass = \"text-green\";\n course.StatusDesc = \"synced\";\n }\n });\n }\n /**\r\n * Redirect to Course Session\r\n */\n\n\n function gotoCourse(course) {\n if ($scope.type == \"ground\") {\n $location.path('/groundcourse/' + course.Id + '/' + $scope.duty.Id + \"/\" + $scope.duty.DutyDateS);\n } else if ($scope.type == \"crewroute\") {\n $location.path('/flightcourse/' + course.Id + '/' + $scope.dutyNo + '/' + $scope.dutyDay + '/' + course.FullDate);\n } else if ($scope.type == \"flight\") {\n $location.path('/flightcourse/' + course.Id + '/' + $scope.dutyNo + '/' + $scope.dutyDay + '/' + course.FullDate + '/' + Number($routeParams.flightId));\n }\n }\n }\n\n return {\n restrict: 'E',\n templateUrl: \"views/Training/training-menu.tpl.html\",\n scope: {\n type: '@',\n id: '=',\n dutyNo: '=',\n dutyDay: '='\n },\n terminal: true,\n link: link\n };\n }\n})();\n\"use strict\";\n\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance\"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === \"[object Arguments]\") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('TrainingSessionFactory', TrainingSessionFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name TrainingSessionFactory\r\n * @description \r\n * Add, Update, Delete and Get Training Courses.\r\n * @ngInject\r\n */\n\n function TrainingSessionFactory(IndexedDBService, CourseFactory, $http, apiUrl, GroundDutyFactory, $filter) {\n /**\r\n * Initialize Session\r\n * @memberof TrainingSessionFactory\r\n */\n function Session() {\n this.Id = null;\n }\n\n var objType = 'TrainingSessions';\n var objCallback = Session;\n var service = {\n getAll: getAll,\n getSession: getSession,\n setSession: setSession,\n updateSession: updateSession,\n getSessionTrainees: getSessionTrainees,\n submitSession: submitSession,\n remove: remove,\n authorizeTrainee: authorizeTrainee,\n getDutySessions: getDutySessions,\n applyTraineeInfoToSession: applyTraineeInfoToSession,\n releaseSession: releaseSession,\n createFlatHistorySullabusItem: createFlatHistorySullabusItem\n };\n /**\r\n * Get all ground training sessions\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\n\n function getAll(callback) {\n IndexedDBService.getAll(objType).then(function (results) {\n callback(results);\n });\n }\n\n ;\n /**\r\n * Get session By day and courseId\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\n\n function getSession(courseId, day, dutyId, afterRefresh, callback, errorCallback) {\n IndexedDBService.getById(objType, [day, courseId, dutyId]).then(function (session) {\n CourseFactory.getCourseFromStorage(courseId, function (course) {\n if (course && !course.HasLimitedInfo && course.CrewCoursePhases && course.CourseTrainees) {\n mergeCourseWithSession(course, session, dutyId, afterRefresh);\n }\n\n callback(course);\n }, errorCallback);\n })[\"catch\"](errorCallback);\n }\n\n function getDutySessions(day, dutyId, callback) {\n IndexedDBService.getAll(objType).then(function (results) {\n results = results.filter(function (x) {\n return x.day == day && x.dutyId == dutyId;\n });\n callback(results);\n });\n }\n /**\r\n * Remove session By day,dutyID (Optional) and courseId\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\n\n\n function remove(courseId, day, dutyId, callback, errorCallback) {\n IndexedDBService.remove(objType, [day, courseId, dutyId]).then(callback)[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Get session Trainees By day and courseId\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\n\n function getSessionTrainees(courseId, day, dutyId, callback, errorCallback) {\n IndexedDBService.getById(objType, [day, courseId, dutyId]).then(function (session) {\n var trainees = session && session.trainees ? session.trainees : [];\n callback(trainees);\n })[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Set session\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\n\n function setSession(session, callback, errorCallback) {\n IndexedDBService.getById(objType, [session.day, session.courseId, session.dutyId]).then(function (result) {\n if (result) {\n saveSessionToStorage(session).then(callback)[\"catch\"](errorCallback);\n ;\n } else {\n addSessionToStorage(session).then(callback)[\"catch\"](errorCallback);\n }\n })[\"catch\"](errorCallback);\n }\n\n ;\n /**\r\n * Set session\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\n\n function updateSession(trainees, session, courseId, day, dutyId, callback, errorCallback) {\n IndexedDBService.getById(objType, [day, courseId, dutyId]).then(function (localSession) {\n var isNewSession = false;\n\n if (!localSession) {\n localSession = {\n courseId: courseId,\n day: day,\n dutyId: dutyId,\n trainees: []\n };\n isNewSession = true;\n } else {\n localSession.trainees = [];\n }\n\n if (session) {\n localSession.Media = session.Media;\n localSession.ReleasedPhase = session.ReleasedPhase;\n localSession.TraineeEligibilty = session.TraineeEligibilty;\n }\n\n trainees.forEach(function (trainee) {\n localSession.trainees.push(trainee);\n });\n\n if (isNewSession) {\n addSessionToStorage(localSession).then(callback)[\"catch\"](errorCallback);\n } else {\n saveSessionToStorage(localSession).then(callback)[\"catch\"](errorCallback);\n }\n })[\"catch\"](errorCallback);\n }\n\n function mergeCourseWithSession(course, session, dutyId, afterRefresh) {\n course.HasLimitedSession = session == undefined;\n var hasPreviousSessions = mergeSyllabusWithHistory(course.CourseTrainees, course.CrewCoursePhases);\n filterTraineesByEligibility(dutyId, course, session, afterRefresh);\n course.CrewCoursePhases.forEach(function (phase) {\n calculatePhaseStatus(phase, course, session);\n });\n course.selectedPhase = getSelectedPhase(course); // Calculate eligible trainees phase status\n\n course.CourseTrainees.forEach(function (trainee) {\n var traineePhase = trainee.Phases.find(function (x) {\n return x.PhaseId == course.selectedPhase.PhaseId;\n });\n\n if (traineePhase) {\n trainee.ActivePhaseStatus = traineePhase.PhaseStatus;\n } else {\n trainee.ActivePhaseStatus = \"Pending\";\n }\n\n trainee.Selectable = trainee.ActivePhaseStatus == \"InProgress\";\n }); //Filter By Role: Filter out trainees that have a flight crew role\n\n if (course.selectedPhase.FilterByRole) {\n course.CourseTrainees.filter(function (x) {\n return x.Selectable && x.PositionCode != 'SA' && x.PositionCode != 'FA';\n }).forEach(function (flightCrewTrainee) {\n flightCrewTrainee.EligibilityStatus = false;\n flightCrewTrainee.EligibilityDesc = \"InvalidRole\";\n course.NonEligibleTrainees.push(flightCrewTrainee);\n });\n } // Non InProgress trainees will be marked as NonEligible (remove further ahead trainees on multiple InProgress phases)\n\n\n course.CourseTrainees.filter(function (x) {\n return !x.Selectable;\n }).forEach(function (invalidPhaseTrainee) {\n invalidPhaseTrainee.EligibilityStatus = false;\n invalidPhaseTrainee.EligibilityDesc = \"AlreadySubmitted\";\n course.NonEligibleTrainees.push(invalidPhaseTrainee);\n });\n course.CourseTrainees = course.CourseTrainees.filter(function (x) {\n return x.EligibilityStatus;\n }); // Get trainee sessions\n\n course.CourseTrainees.forEach(function (trainee) {\n var sessionTrainee = session ? session.trainees.find(function (x) {\n return x.CrewId == trainee.CrewId;\n }) : null;\n\n if (sessionTrainee) {\n trainee.Session = sessionTrainee.Session;\n sessionTrainee.Session.AdditionalTrainingStatus = sessionTrainee.AdditionalTrainingStatus;\n } else {\n var _trainee$Session;\n\n trainee.Session = (_trainee$Session = {\n Released: course.selectedPhase.ModuleType == \"Training\" ? false : true,\n CrewId: trainee.CrewId,\n Items: [],\n Absent: false,\n DayGrading: {\n Comments: null,\n Grade: null,\n Competences: []\n },\n ReleaseGrading: {\n Comments: null,\n Grade: null,\n Competences: []\n },\n NeedsAdditionalTraining: false,\n AdditionalTrainingRemarks: null,\n CompleteAdditionalTraining: false\n }, _defineProperty(_trainee$Session, \"NeedsAdditionalTraining\", false), _defineProperty(_trainee$Session, \"AdditionalTrainingStatus\", null), _trainee$Session);\n }\n });\n /* Set default values for release option\r\n Training Modules: 'No' release as default\r\n Check Module: 'Yes' release as default\r\n */\n\n course.ReleasedPhase = course.selectedPhase.ModuleType == \"Training\" ? false : true;\n\n if (session) {\n course.Media = session.Media;\n course.ReleasedPhase = session.ReleasedPhase;\n course.TraineeEligibilty = session.TraineeEligibilty;\n }\n }\n\n function getSelectedPhase(course) {\n var hasSelectedPhase = false;\n var phases = course.CrewCoursePhases;\n phases.forEach(function (phase, index, array) {\n phase.isFirst = index == 0;\n phase.isLast = index + 1 == array.length; // Select the first InProgress & selected phase\n\n if (!hasSelectedPhase && phase.Status == \"InProgress\" && phase.isSelected) {\n phase.Selected = true;\n hasSelectedPhase = true;\n }\n }); // Select the first InProgress phase\n\n if (!hasSelectedPhase && phases.some(function (x) {\n return x.Status == \"InProgress\";\n })) {\n phases.find(function (x) {\n return x.Status == \"InProgress\";\n }).Selected = true;\n hasSelectedPhase = true;\n }\n\n if (!hasSelectedPhase) {\n phases.find(function (x) {\n return x.isFirst;\n }).Selected = true;\n }\n\n var selectedPhase = phases.find(function (x) {\n return x.Selected;\n });\n return selectedPhase;\n }\n\n function filterTraineesByEligibility(dutyId, course, session, afterRefresh) {\n var _course$CourseTrainee;\n\n var groundDuty = GroundDutyFactory.getGroundDutyFromStorage(dutyId); // Trainee Eligiblity cases\n // 1. After refresh - Save newly fetched eligibility in session\n // 2. No refresh & Session exists - Get last fetched eligibility from session\n // 3. No refresh & No session exists - Rely on previously fetched eligibility (different duty - same course)\n\n var traineeEligibility = course.TraineeEligibilty;\n\n if (!afterRefresh && session && session.TraineeEligibilty) {\n traineeEligibility = session.TraineeEligibilty;\n }\n\n if (session) session.TraineeEligibilty = traineeEligibility; //update session eligibility\n // Get ground duty trainees without any training records\n\n var trainees = getGroundCourseTrainees(groundDuty, course.Id);\n var inactiveTrainees = trainees.filter(function (x) {\n return !course.CourseTrainees.some(function (z) {\n return z.CrewId == x.CrewId;\n });\n }); //Exclude Non valid trainees\n\n var eligibleTraineeIds = Object.keys(traineeEligibility).filter(function (x) {\n return traineeEligibility[x] == \"NotStarted\" || traineeEligibility[x] == \"ValidPhase\" || traineeEligibility[x] == \"FailedCertificate\";\n }).map(Number);\n var eligibleTrainees = inactiveTrainees.filter(function (x) {\n return eligibleTraineeIds.includes(x.CrewId);\n });\n eligibleTrainees.forEach(function (trainee) {\n trainee.EligibilityStatus = true;\n });\n createNewPhaseTrainees(groundDuty, course, eligibleTrainees); // Merge eligibleTrainees (inactive) with CourseTrainees (eligible & active)\n\n course.CourseTrainees.forEach(function (trainee) {\n trainee.EligibilityStatus = true;\n });\n\n (_course$CourseTrainee = course.CourseTrainees).push.apply(_course$CourseTrainee, _toConsumableArray(eligibleTrainees)); // Non eligible trainees\n\n\n var nonEligibleTrainees = inactiveTrainees.filter(function (x) {\n return !eligibleTraineeIds.includes(x.CrewId);\n });\n course.NonEligibleTrainees = nonEligibleTrainees;\n nonEligibleTrainees.forEach(function (trainee) {\n trainee.EligibilityStatus = false;\n trainee.EligibilityDesc = traineeEligibility[trainee.CrewId];\n }); // Result:\n // CourseTrainees = eligible trainees (active or new)\n // Non EligibleTrainees\n }\n /**\r\n * Create first phase foreach trainee\r\n * @param {object} groundDuty \r\n * @param {object} course \r\n * @param {array} trainees Eligible trainees that haven't yet started training\r\n */\n\n\n function createNewPhaseTrainees(groundDuty, course, trainees) {\n //Match GroundDutyNos with PhaseDutyNos\n var crewCoursePhaseDutyNos = [];\n var groundDutyTraineeDutyNos = [];\n course.CrewCoursePhases.forEach(function (coursePhase) {\n crewCoursePhaseDutyNos = crewCoursePhaseDutyNos.concat(coursePhase.GroundDutyCodes);\n });\n groundDuty.Trainees.forEach(function (relatedDuty) {\n groundDutyTraineeDutyNos.push(relatedDuty.GroundDutyNo.toString());\n });\n var relatedDutyNos = crewCoursePhaseDutyNos.filter(function (x) {\n return groundDutyTraineeDutyNos.includes(x);\n });\n var relatedPhases = course.CrewCoursePhases.filter(function (x) {\n return x.GroundDutyCodes.some(function (gdc) {\n return relatedDutyNos.includes(gdc);\n });\n }); //From related phases, select first in order\n\n relatedPhases = $filter('orderBy')(relatedPhases, 'OrderNo');\n var firstPhase = relatedPhases[0];\n trainees.forEach(function (trainee) {\n trainee.Phases = [{\n PhaseId: firstPhase.PhaseId,\n PhaseStatus: \"InProgress\",\n RepeatRequestedItems: [],\n isSelected: true //selectedPhase\n\n }];\n });\n }\n\n function getGroundCourseTrainees(groundDuty, courseId) {\n var trainees = [];\n groundDuty.RelatedGroundDuties.filter(function (x) {\n return x.Courses && x.Courses.map(function (course) {\n return course.CourseId;\n }).includes(courseId);\n }).forEach(function (item) {\n item.CrewMembers.forEach(function (crewMember) {\n var trainee = {\n AimsId: crewMember.AIMS_ID,\n CrewId: crewMember.Id,\n Name: crewMember.Name,\n PositionCode: crewMember.PositionCode\n };\n trainees.push(trainee);\n });\n });\n return trainees;\n }\n\n function calculatePhaseStatus(phase, course) {\n course.CourseTrainees.forEach(function (trainee) {\n var traineePhase = trainee.Phases.find(function (x) {\n return x.PhaseId == phase.PhaseId;\n });\n\n if (traineePhase && traineePhase.PhaseStatus == \"InProgress\") {\n phase.Status = \"InProgress\";\n } else if (!traineePhase && phase.Status != \"InProgress\") {\n phase.Status = \"Pending\";\n } else if (traineePhase && traineePhase.PhaseStatus == \"Completed\" && phase.Status != \"InProgress\") {\n phase.Status = \"Completed\";\n } //Selected phase, If at least one trainee has it selected\n\n\n if (traineePhase && !phase.isSelected) {\n phase.isSelected = traineePhase.isSelected;\n }\n });\n }\n\n function mergeSyllabusWithHistory(trainees, phases) {\n var flatSullabusItems = [];\n trainees.forEach(function (trainee) {\n trainee.Phases.forEach(function (phase) {\n phase.Sessions.forEach(function (session) {\n session.Items.forEach(function (item) {\n var flatItem = createFlatHistorySullabusItem(trainee, phase, session, item);\n flatSullabusItems.push(flatItem);\n });\n });\n });\n });\n phases.filter(function (x) {\n return x.Syllabus;\n }).forEach(function (phase, index, array) {\n phase.Syllabus.SyllabusItems.forEach(function (syllabusItem) {\n syllabusItem.History = flatSullabusItems.filter(function (item) {\n return item.ItemId == syllabusItem.Id;\n });\n });\n });\n var hasPreviousSessions = flatSullabusItems.length > 0;\n return hasPreviousSessions;\n }\n\n function createFlatHistorySullabusItem(trainee, phase, session, item) {\n var flatItem = {\n CrewId: trainee.CrewId,\n PhaseId: phase.PhaseId,\n SessionId: session.SessionId,\n SessionComments: session.SessionComments,\n SubmissionDate: item.SubmissionDate,\n RepeatRequired: item.RepeatRequired,\n Tries: item.Tries,\n ItemId: item.SyllabusItemId,\n Grade: session.Grade,\n GradeType: session.GradeType,\n InstructorName: session.InstructorName,\n InstructorAimsId: session.InstructorAimsId\n };\n return flatItem;\n }\n /**\r\n * Add Session to Storage\r\n * @memberof TrainingSessionFactory\r\n * @param {object} Session\r\n */\n\n\n function addSessionToStorage(session) {\n return IndexedDBService.add(objType, session);\n }\n\n ;\n /**\r\n * Update Session to Storage\r\n * @memberof TrainingSessionFactory\r\n * @param {object} Session\r\n */\n\n function saveSessionToStorage(session) {\n return IndexedDBService.put(objType, session);\n }\n\n ;\n\n function submitSession(submittedSession, callback) {\n var traingingApiURL = apiUrl + '/Training/SubmitTraining';\n return $http.post(traingingApiURL, submittedSession, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n /**\r\n * Authorize Trainee for submission\r\n * @param {string} credentials Trainee's password, username, crewId, position\r\n * @param {function} callback \r\n * @param {function} errorCallback \r\n */\n\n\n function authorizeTrainee(credentials, callback, errorCallback) {\n return $http.post(apiUrl + '/Training/AuthorizeTrainee', credentials, {\n 'Content-Type': 'application/json'\n }).then(callback)[\"catch\"](errorCallback);\n }\n\n function applyTraineeInfoToSession(course, courseId, day, dutyId, callback, errorCallback) {\n IndexedDBService.getById(objType, [day, courseId, dutyId]).then(function (localSession) {\n var isNewSession = false;\n\n if (!localSession) {\n localSession = {\n courseId: courseId,\n day: day,\n dutyId: dutyId,\n trainees: [],\n TraineeEligibilty: course.TraineeEligibilty,\n CourseTrainees: course.CourseTrainees\n };\n isNewSession = true;\n } else {\n localSession.TraineeEligibilty = course.TraineeEligibilty;\n localSession.CourseTrainees = course.CourseTrainees;\n }\n\n if (isNewSession) {\n addSessionToStorage(localSession).then(callback)[\"catch\"](errorCallback);\n } else {\n saveSessionToStorage(localSession).then(callback)[\"catch\"](errorCallback);\n }\n })[\"catch\"](errorCallback);\n }\n\n function releaseSession(submittedSessions, callback, errorCallback) {\n var traingingApiURL = apiUrl + '/Training/ReleaseSession';\n return $http.post(traingingApiURL, submittedSessions, {\n 'Content-Type': 'application/json'\n }).then(callback)[\"catch\"](errorCallback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n // Warning!!! This an auto generated file. Any Changes will be lost. If u want to add or edit go to config.json \n a3_cabin_reports.constant(\"version\", \"appVersion_20170424105730\");\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('DebugCtrl', DebugCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name DebugCtrl\r\n * @description \r\n * Manage Debug view\r\n * @ngInject\r\n */\n\n function DebugCtrl($location, $scope, UserFactory, DebugFactory, localStorageMD5Service) {\n $scope.isSecure = UserFactory.isSecure();\n $scope.adminkey = \"\";\n $scope.authorized = false; // show logged user info\n\n var user = UserFactory.getUser();\n $scope.logged_user_info = \"-user has not logged in-\";\n if (user) $scope.logged_user_info = user.aimsId + ' - ' + user.name;\n $scope.storedValues = [];\n $scope.addKeyName = null;\n $scope.checkAuthorized = checkAuthorized;\n $scope.refreshStoredValues = refreshStoredValues;\n $scope.add = add;\n $scope.update = update;\n $scope[\"delete\"] = deleteFromStorage;\n $scope.exit = exit;\n $scope.updateAll = updateAll;\n /**\r\n * Update all the local storage \r\n * @memberof DebugCtrl\r\n */\n\n function updateAll() {\n try {\n var items = JSON.parse($scope.updateAllJson);\n\n for (var i = 0; i < items.length; i++) {\n var obj = null;\n if (items[i].value != '') obj = angular.fromJson(items[i].value);\n localStorageMD5Service.set(items[i].key, obj);\n }\n\n $scope.refreshStoredValues();\n } catch (e) {\n alert('Error: ' + e.message || e.errorMessage);\n }\n }\n /**\r\n * Add a new local storage key\r\n * @memberof DebugCtrl\r\n */\n\n\n function add() {\n try {\n var key = $scope.addKeyName;\n if (!key || key == '') return false;\n var keys = localStorageMD5Service.keys();\n\n if (keys && keys.indexOf(key) > 0) {\n alert('Key exists!');\n return false;\n }\n\n localStorageMD5Service.set(key, [\"empty\"]);\n $scope.refreshStoredValues();\n $scope.addKeyName = null;\n } catch (e) {\n alert('Error: ' + e.message || e.errorMessage);\n }\n }\n /**\r\n * Update an existing local storage key\r\n * @memberof DebugCtrl\r\n * @param {object} item\r\n */\n\n\n function update(item) {\n try {\n var obj = null;\n if (item.value != '') obj = angular.fromJson(item.value);\n localStorageMD5Service.set(item.key, obj);\n $scope.refreshStoredValues();\n } catch (e) {\n alert('Error: ' + e.message || e.errorMessage);\n }\n }\n /**\r\n * delete an existing local storage key\r\n * @memberof DebugCtrl\r\n * @param {object} item\r\n */\n\n\n function deleteFromStorage(item) {\n if (confirm('Confirm deletion of key ' + item.key)) {\n localStorageMD5Service.remove(item.key);\n $scope.refreshStoredValues();\n }\n }\n /**\r\n * Check if the user is authorized in order to view key values\r\n * @memberof DebugCtrl\r\n */\n\n\n function checkAuthorized() {\n var verify = localStorageMD5Service.md5hash($scope.adminkey);\n DebugFactory.CheckAuthorized(verify, function (responseData) {\n if ($scope.authorized != responseData.data.data) {\n $scope.authorized = responseData.data.data;\n $scope.refreshStoredValues();\n }\n })[\"catch\"](function (error) {\n $scope.authorized = responseData.Data;\n console.error('Wrong Password', error.status, error.statusText);\n });\n }\n /**\r\n * Refresh values from localstorage\r\n * @memberof DebugCtrl\r\n */\n\n\n function refreshStoredValues() {\n var values = [];\n\n if ($scope.authorized) {\n var keys = localStorageMD5Service.keys();\n\n if (keys) {\n var key, value, sizeActual, error;\n\n for (var i = 0; i < keys.length; i++) {\n key = keys[i];\n\n try {\n value = localStorageMD5Service.get(key);\n value = angular.toJson(value);\n sizeActual = localStorageMD5Service.usedSize(key);\n error = null;\n } catch (e) {\n error = e.message || e.errorMessage;\n }\n\n values.push({\n key: key,\n value: value,\n error: error,\n size: value ? value.length : 0,\n sizeActual: sizeActual\n });\n }\n }\n }\n\n $scope.storedValues = values;\n }\n /**\r\n * Redirect to main Menu\r\n * @memberof DebugCtrl\r\n */\n\n\n function exit() {\n $location.path(\"/\");\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('DebugFactory', DebugFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name DebugFactory\r\n * @description \r\n * Authorize check from API ...\r\n * @ngInject\r\n */\n\n function DebugFactory(GenericService, $http, $q, apiUrl, LogService) {\n /**\r\n * Initialize Debug\r\n * @memberof DebugFactory\r\n */\n var service = {\n CheckAuthorized: CheckAuthorized\n };\n\n function CheckAuthorized(value, callback) {\n return $http.get(apiUrl + '/debug/CheckAuthorized/' + value, {\n 'Content-Type': 'application/json'\n }).then(callback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('ResetDeviceCtrl', ResetDeviceCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ResetDeviceCtrl\r\n * @description \r\n * Manage Reset view\r\n * @ngInject\r\n */\n\n function ResetDeviceCtrl($location, $scope, DataCleanerFactory, UserFactory) {\n $scope.isSecure = UserFactory.isSecure(); // show logged user info\n\n var user = UserFactory.getUser();\n $scope.logged_user_info = \"-user has not logged in-\";\n if (user) $scope.logged_user_info = user.aimsId + ' - ' + user.name;\n $scope.resetDevice = resetDevice;\n $scope.cancelReset = cancelReset;\n /**\r\n * Reset Device storage\r\n * @memberof ResetDeviceCtrl\r\n */\n\n function resetDevice() {\n DataCleanerFactory.deleteAllData();\n bootbox.alert(\"Your device has been reset.\", function () {\n $location.path(\"/login\");\n $scope.$apply();\n });\n }\n /**\r\n * Cancel Reset and go to main page.\r\n * @memberof ResetDeviceCtrl\r\n */\n\n\n function cancelReset() {\n $location.path(\"/\");\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('WifiAvailabilityFactory', WifiAvailabilityFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name WifiAvailabilityFactory\r\n * @description \r\n * Storage of aircraft registrations with Wi-Fi connectivity.\r\n * @ngInject\r\n */\n\n function WifiAvailabilityFactory(GenericService) {\n var objType = 'WifiAvailability';\n var objCallback = WifiAvailability;\n /**\r\n * Initialize the WifiAvailability\r\n * @memberof WifiAvailabilityFactory\r\n */\n\n function WifiAvailability() {\n this.Registrations = [];\n }\n\n var service = {\n setRegistrationsToStorage: setRegistrationsToStorage,\n getRegistrationsFromStorage: getRegistrationsFromStorage\n };\n /**\r\n * Save registrations with Wi-Fi connectivity to storage\r\n * @param {array} objList A list of aircraft registrations\r\n */\n\n function setRegistrationsToStorage(objList) {\n if (objList != null) {\n var registrations = {\n registrations: objList\n };\n GenericService.saveOne(registrations, objType, objCallback);\n }\n }\n /**\r\n * Get registrations from storage\r\n */\n\n\n function getRegistrationsFromStorage() {\n return GenericService.getOne(objType, objCallback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('wifiPrograms', wifiPrograms);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name wifiPrograms\r\n * @restrict EA\r\n * @description\r\n * Implementation of wifiPrograms\r\n *\r\n * Initialize the wifi programs panel needs to have flight in scope\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function wifiPrograms() {\n /**\r\n * Initialize wifiVouchers\r\n * @memberof wifiVouchers\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\n function link(scope, element, attrs) {// scope.textAndSurfCodes = [];\n // scope.streamCodes = [];\n }\n\n return {\n restrict: 'EA',\n terminal: true,\n templateUrl: 'views/WifiVouchers/wifiPrograms.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.directive('wifiVouchers', wifiVouchers);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name wifiVouchers\r\n * @restrict EA\r\n * @description\r\n * Implementation of wifiVouchers\r\n *\r\n * Initialize the wifi vouchers panel needs to have flight in scope\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\n\n function wifiVouchers(WifiVouchersFactory, WifiAvailabilityFactory, $timeout) {\n /**\r\n * Initialize wifiVouchers\r\n * @memberof wifiVouchers\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\n function link(scope, element, attrs) {\n var wifiAvailability = WifiAvailabilityFactory.getRegistrationsFromStorage();\n\n if (wifiAvailability) {\n scope.supportsWifi = wifiAvailability.registrations.includes(scope.flight.AcTailNo);\n } else {\n scope.supportsWifi = false;\n }\n\n scope.retrieve = retrieve; // scope.createVoucher = createVoucher;\n\n scope.showPanel = '';\n scope.submitMessage = '';\n scope.pnrNo = null;\n scope.wifiVouchersCodes = [];\n scope.textAndSurfCodes = [];\n scope.streamCodes = [];\n scope.isFlightView = true;\n\n function retrieve(pnrNo) {\n if (scope.isOffline) {\n scope.showPanel = \"offline\";\n } else {\n scope.showPanel = \"loading\";\n var RequestWifiVouchers = {\n PNR: pnrNo,\n FlightId: scope.flight.FlightId,\n Flight: scope.paxInfo.STDLocal\n };\n WifiVouchersFactory.retrieveWifiVouchers(RequestWifiVouchers).then(function (res) {\n return handleSubmitResponse(res);\n });\n }\n }\n\n function handleSubmitResponse(res) {\n if (res.success) {\n scope.notRetrieved = false;\n scope.textAndSurfCodes = [];\n scope.streamCodes = [];\n manageResponseMessage(\"success\", res.message);\n scope.wifiVouchersCodes = res.data;\n scope.wifiVouchersCodes.forEach(function (code) {\n if (code.Type == 'Text & Surf') {\n scope.textAndSurfCodes.push(code.VoucherCode);\n }\n });\n scope.wifiVouchersCodes.forEach(function (code) {\n if (code.Type == 'Stream') {\n scope.streamCodes.push(code.VoucherCode);\n }\n });\n } else {\n manageResponseMessage(\"failure\", res.message);\n }\n }\n /**\r\n * Manage message alerts\r\n * @param {string} panelToShow \r\n * @param {string} message \r\n */\n\n\n function manageResponseMessage(panelToShow, message) {\n scope.submitMessage = message;\n scope.showPanel = panelToShow;\n }\n }\n\n return {\n restrict: 'EA',\n terminal: true,\n templateUrl: 'views/WifiVouchers/wifiVouchers.tpl.html',\n scope: false,\n link: link\n };\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('WifiVouchersFactory', WifiVouchersFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name WifiVouchersFactory\r\n * @description \r\n * Get Wifi VouchersFactory.\r\n * @ngInject\r\n */\n\n function WifiVouchersFactory($http, apiUrl) {\n var submitResponseObj = {\n success: false,\n message: '',\n data: ''\n };\n var service = {\n retrieveWifiVouchers: retrieveWifiVouchers,\n createWifiVoucher: createWifiVoucher\n };\n /**\r\n * Retrieve Wifi Vouchers\r\n * @memberof WifiVouchersFactory\r\n * @param {function} callback \r\n */\n\n function retrieveWifiVouchers(requestObj) {\n var objectToAdd = requestObj;\n return $http.post(apiUrl + '/WifiVouchers/RetrieveVouchers/', requestObj, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return retrieveVouchersSuccessCallBack(res, objectToAdd);\n })[\"catch\"](function (res) {\n return vouchersFailedCallBack(res);\n });\n }\n /**\r\n * The callback function upon successful retrieve\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} submitResponseObj\r\n */\n\n\n function retrieveVouchersSuccessCallBack(res, objectToAdd) {\n submitResponseObj.success = res.data.success;\n\n if (res.data.success && objectToAdd.PNR != null) {\n submitResponseObj.message = \"Success! Your input has been sent\";\n submitResponseObj.data = res.data.data.Result;\n } else if (res.data.success && objectToAdd.PNR == null) {\n submitResponseObj.message = \"You have to fill PNR No\";\n } else {\n submitResponseObj.message = res.data.errorMessage;\n }\n\n return submitResponseObj;\n }\n /**\r\n * Create Wifi Vouchers\r\n * @memberof WifiVouchersFactory\r\n * @param {function} callback \r\n */\n\n\n function createWifiVoucher(requestObj) {\n var objectToAdd = requestObj;\n return $http.post(apiUrl + '/WifiVouchers/CreateVoucher/', requestObj, {\n 'Content-Type': 'application/json'\n }).then(function (res) {\n return createVouchersSuccessCallBack(res, objectToAdd);\n })[\"catch\"](function (res) {\n return vouchersFailedCallBack(res);\n });\n }\n\n function createVouchersSuccessCallBack(res, objectToAdd) {\n submitResponseObj.success = res.data.success;\n\n if (res.data.success && objectToAdd.PNR != null && res.data.data.Result && res.data.data.Result.Vouchers) {\n submitResponseObj.message = \"Success! Your input has been sent\";\n submitResponseObj.data = res.data.data.Result.Vouchers;\n } else {\n submitResponseObj.message = res.data.errorMessage;\n }\n\n return submitResponseObj;\n }\n /**\r\n * The callback function upon failure on retrieve\r\n * @returns {object} submitResponseObj\r\n */\n\n\n function vouchersFailedCallBack(res) {\n submitResponseObj.success = false;\n submitResponseObj.message = \"Oops! Something went wrong\";\n return submitResponseObj;\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('ACSupplyFactory', ACSupplyFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ACSupplyFactory\r\n * @description \r\n * Manage ACSupplies.\r\n * @ngInject\r\n */\n\n function ACSupplyFactory(GenericValuesFactory) {\n /**\r\n * Initialiaze ACSupply object \r\n * @memberof ACSupplyFactory\r\n */\n function ACSupply() {\n this.Code = null;\n }\n\n var callback = ACSupply;\n var type = 'acSupplies';\n var service = {\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n toObjectList: toObjectList,\n getACSuppliesFromStorage: getACSuppliesFromStorage,\n getACSuppliesFromStorageAsStrings: getACSuppliesFromStorageAsStrings,\n setACSuppliesToStorage: setACSuppliesToStorage\n };\n /**\r\n * Extend given ACSupply object \r\n * @memberof ACSupplyFactory\r\n * @param {object} obj The ACSupply object that will be extended\r\n * @returns {object} ACSupply\r\n */\n\n function fromObject(obj) {\n return GenericValuesFactory.fromObject(obj, callback);\n }\n /**\r\n * Extend given ACSupply object list\r\n * @memberof ACSupplyFactory\r\n * @param {array} objList The list of ACSupply objects that will be extended\r\n * @returns {object} ACSupplies\r\n */\n\n\n function fromObjectList(objList) {\n return GenericValuesFactory.fromObjectList(objList, callback);\n }\n /**\r\n * Get all the ACSupply's Code from given list\r\n * @memberof ACSupplyFactory\r\n * @param {array} objectList An object list\r\n * @returns {array} ACSupplies\r\n */\n\n\n function toObjectList(objList) {\n return GenericValuesFactory.objList(objList);\n }\n /**\r\n * Get all the ACSupply objects\r\n * @memberof ACSupplyFactory\r\n * @returns {array} ACSupplies\r\n */\n\n\n function getACSuppliesFromStorage() {\n return GenericValuesFactory.getValuesFromStorage(callback, type);\n }\n /**\r\n * Get all the ACSupply's codes from local storage\r\n * @memberof ACSupplyFactory\r\n * @returns {array} ACSupplies\r\n */\n\n\n function getACSuppliesFromStorageAsStrings() {\n return GenericValuesFactory.getValuesFromStorageAsStrings(callback, type);\n }\n /**\r\n * Set all the ACSupplies\r\n * @memberof ACSupplyFactory\r\n * @param {array} objects A list of ACSupplies.\r\n */\n\n\n function setACSuppliesToStorage(objList) {\n GenericValuesFactory.setValuesToStorage(objList, type);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('AircraftTypeFactory', AircraftTypeFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AircraftTypeFactory\r\n * @description \r\n * Manage Aircraft Types.\r\n * @ngInject\r\n */\n\n function AircraftTypeFactory(GenericValuesFactory) {\n /**\r\n * Initialiaze AircraftType object \r\n * @memberof AircraftTypeFactory\r\n */\n function AircraftType() {\n this.Code = null;\n }\n\n var callback = AircraftType;\n var type = 'aircraftTypes';\n var service = {\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n toObjectList: toObjectList,\n getAircraftTypesFromStorage: getAircraftTypesFromStorage,\n setAircraftTypesToStorage: setAircraftTypesToStorage\n };\n /**\r\n * Extend given AircraftType object \r\n * @memberof AircraftTypeFactory\r\n * @param {object} obj The AircraftType object that will be extended\r\n * @returns {object} AircraftType\r\n */\n\n function fromObject(obj) {\n return GenericValuesFactory.fromObject(obj, callback);\n }\n /**\r\n * Extend given AircraftType object list\r\n * @memberof AircraftTypeFactory\r\n * @param {array} objList The list of AircraftType objects that will be extended\r\n * @returns {object} AircraftTypes\r\n */\n\n\n function fromObjectList(objList) {\n return GenericValuesFactory.fromObjectList(objList, callback);\n }\n /**\r\n * Extend given AircraftType object list\r\n * @memberof AircraftTypeFactory\r\n * @param {array} objList The list of AircraftType objects that will be extended\r\n * @returns {object} AircraftTypes\r\n */\n\n\n function toObjectList(objList) {\n return GenericValuesFactory.objList(objList);\n }\n /**\r\n * Get all the AircraftType objects\r\n * @memberof AircraftTypeFactory\r\n * @returns {array} AircraftTypes\r\n */\n\n\n function getAircraftTypesFromStorage() {\n return GenericValuesFactory.getValuesFromStorage(callback, type);\n }\n /**\r\n * Set all the AircraftTypes\r\n * @memberof AircraftTypeFactory\r\n * @param {array} objects A list of AircraftTypes.\r\n */\n\n\n function setAircraftTypesToStorage(objList) {\n GenericValuesFactory.setValuesToStorage(objList, type);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('BarTrolleyCtrl', BarTrolleyCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name BarTrolleyCtrl\r\n * @description \r\n * Manages the Bar Trolley Modal View\r\n * @ngInject\r\n */\n\n function BarTrolleyCtrl($scope, $uibModalInstance, ModalDialogResultFactory, BarTrolleyFactory, bart) {\n var result = ModalDialogResultFactory.createNew();\n\n if (bart == null) {\n result.Object = BarTrolleyFactory.createNew();\n result.isInsertMode = true;\n } else {\n result.Object = BarTrolleyFactory.fromObject(bart);\n result.isInsertMode = false;\n }\n\n $scope.bart = result.Object;\n $scope.ok = ok;\n $scope.cancel = cancel;\n /**\r\n * Close modal after u check position\r\n * @memberof BarTrolleyCtrl\r\n */\n\n function ok() {\n if (result.Object.Position == null || result.Object.Position == '') result.Object.Position = '-';\n $uibModalInstance.close(result);\n }\n /**\r\n * Close Modal\r\n * @memberof BarTrolleyCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('BarTrolleyFactory', BarTrolleyFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name BarTrolleyFactory\r\n * @description \r\n * Manage Report's BarTrolley.\r\n * @ngInject\r\n */\n\n function BarTrolleyFactory(GenericModalFactory) {\n /**\r\n * Initialiaze BarTrolley object \r\n * @memberof BarTrolleyFactory\r\n */\n function BarTrolley() {\n this.Id = null;\n this.Position = null;\n this.SealFound = null;\n this.SealLeft = null;\n this.Label = 'Bar trolleys';\n this.Photos = [];\n this.PhotoRemarks = null;\n }\n\n var service = {\n createNew: createNew,\n fromObject: fromObject,\n deleteFromList: deleteFromList\n };\n /**\r\n * Create a new BarTrolley object \r\n * @memberof BarTrolleyFactory\r\n * @returns {object} BarTrolley\r\n */\n\n function createNew() {\n return GenericModalFactory.createNew(BarTrolley);\n }\n /**\r\n * Extend given BarTrolley object \r\n * @memberof BarTrolleyFactory\r\n * @param {object} obj The BarTrolley object that will be extended\r\n * @returns {object} BarTrolley\r\n */\n\n\n function fromObject(obj) {\n return GenericModalFactory.fromObject(obj, BarTrolley);\n }\n /**\r\n * Delete BarTrolley object from given list\r\n * @memberof BarTrolleyFactory\r\n * @param {object} obj The BarTrolley object that will be deleted\r\n * @returns {array} BarTrollies\r\n */\n\n\n function deleteFromList(obj, objList) {\n return GenericModalFactory.deleteFromList(obj, objList);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CCMSFactory', CCMSFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CCMSFactory\r\n * @description \r\n * Manage CCMS.\r\n * @ngInject\r\n */\n\n function CCMSFactory(GenericService) {\n /**\r\n * Initialiaze CCMS object \r\n * @memberof CCMSFactory\r\n */\n function CCMS() {\n this.Aircraft = null;\n this.Positions = new Array();\n this.CrewComments = new Array();\n }\n\n var objType = 'ccms';\n var objCallback = CCMS;\n var service = {\n getCCMSFromStorage: getCCMSFromStorage,\n setCCMSToStorage: setCCMSToStorage\n };\n /**\r\n * Get all the CCMS objects\r\n * @memberof CCMSFactory\r\n * @returns {array} CCMS\r\n */\n\n function getCCMSFromStorage() {\n return GenericService.list(objType, objCallback);\n }\n /**\r\n * Set all the CCMS\r\n * @memberof CCMSFactory\r\n * @param {array} objects A list of CCMS.\r\n */\n\n\n function setCCMSToStorage(ccms) {\n GenericService.saveAll(ccms, objType, objCallback);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('CCMSCrewPositionCtrl', CCMSCrewPositionCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CCMSCrewPositionCtrl\r\n * @description \r\n * Manages the CCMS Crew Position Modal View\r\n * @ngInject\r\n */\n\n function CCMSCrewPositionCtrl($scope, $uibModalInstance, ModalDialogResultFactory, CCMSCrewPositionFactory, crew) {\n var result = ModalDialogResultFactory.createNew();\n\n if (crew == null) {\n result.Object = CCMSCrewPositionFactory.createNew();\n result.Object.IsManual = true;\n result.isInsertMode = true;\n } else {\n result.Object = CCMSCrewPositionFactory.fromObject(crew);\n result.isInsertMode = false;\n }\n\n $scope.crew = result.Object;\n $scope.ok = ok;\n $scope.cancel = cancel;\n /**\r\n * Close modal after u check position\r\n * @memberof CCMSCrewPositionCtrl\r\n */\n\n function ok() {\n if (result.Object.CrewId == null || result.Object.CrewId == '') result.Object.CrewId = '-';\n $uibModalInstance.close(result);\n }\n /**\r\n * Close Modal\r\n * @memberof CCMSCrewPositionCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('CCMSCrewPositionFactory', CCMSCrewPositionFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CCMSCrewPositionFactory\r\n * @description \r\n * Manage Report's CCMSCrewPositions.\r\n * @ngInject\r\n */\n\n function CCMSCrewPositionFactory(GenericModalFactory) {\n /**\r\n * Initialiaze CCMSCrewPosition object \r\n * @memberof CCMSCrewPositionFactory\r\n */\n function CCMSCrewPosition() {\n this.Id = null;\n this.CrewId = null;\n this.Initials = null;\n this.Name = null;\n this.Position = null;\n this.CCMS = null;\n this.IsManual = false;\n this.CrewComments = null;\n this.HasCrewComments = false;\n this.needsAdditionalFeedback = false;\n this.HasAdditionalFeedbackComments = false;\n this.AdditionalFeedbackId = null;\n this.FeedbackAuthorName = null;\n this.Route = null;\n }\n\n var service = {\n createNew: createNew,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n deleteFromList: deleteFromList\n };\n /**\r\n * Create a new CCMSCrewPosition object \r\n * @memberof CCMSCrewPositionFactory\r\n * @returns {object} CCMSCrewPosition\r\n */\n\n function createNew() {\n return GenericModalFactory.createNew(CCMSCrewPosition);\n }\n /**\r\n * Extend given CCMSCrewPosition object \r\n * @memberof CCMSCrewPositionFactory\r\n * @param {object} obj The CCMSCrewPosition object that will be extended\r\n * @returns {object} CCMSCrewPosition\r\n */\n\n\n function fromObject(obj) {\n return GenericModalFactory.fromObject(obj, CCMSCrewPosition);\n }\n /**\r\n * Delete CCMSCrewPosition object from given list\r\n * @memberof CCMSCrewPositionFactory\r\n * @param {object} obj The CCMSCrewPosition object that will be deleted\r\n * @returns {array} CCMSCrewPositions\r\n */\n\n\n function deleteFromList(obj, objList) {\n return GenericModalFactory.deleteFromList(obj, objList);\n }\n /**\r\n * Extend given CCMSCrewPosition object List \r\n * @memberof CCMSCrewPositionFactory\r\n * @param {object} obj The CCMSCrewPosition object that will be extended\r\n * @returns {array} CCMSCrewPositions\r\n */\n\n\n function fromObjectList(objList) {\n return GenericModalFactory.fromObjectList(objList, CCMSCrewPosition);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('FirstAidKitCtrl', FirstAidKitCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FirstAidKitCtrl\r\n * @description \r\n * Manages the First Aid Kit Modal View\r\n * @ngInject\r\n */\n\n function FirstAidKitCtrl($scope, $uibModalInstance, ModalDialogResultFactory, FirstAidKitFactory, fak, IsEMK) {\n var result = ModalDialogResultFactory.createNew();\n console.log(\"emk \" + IsEMK);\n\n if (fak == null) {\n result.Object = FirstAidKitFactory.createNew();\n result.Object.IsEMK = IsEMK;\n result.isInsertMode = true;\n } else {\n result.Object = FirstAidKitFactory.fromObject(fak);\n result.isInsertMode = false;\n }\n\n $scope.fak = result.Object;\n $scope.IsEMK = IsEMK;\n $scope.ok = ok;\n $scope.cancel = cancel;\n /**\r\n * Close modal after u check position\r\n * @memberof FirstAidKitCtrl\r\n */\n\n function ok() {\n if (result.Object.Position == null || result.Object.Position == '') result.Object.Position = '-';\n $uibModalInstance.close(result);\n }\n /**\r\n * Close Modal\r\n * @memberof FirstAidKitCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('FirstAidKitFactory', FirstAidKitFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FirstAidKitFactory\r\n * @description \r\n * Manage Report's FirstAidKits.\r\n * @ngInject\r\n */\n\n function FirstAidKitFactory(GenericModalFactory) {\n /**\r\n * Initialiaze FirstAidKit object \r\n * @memberof FirstAidKitFactory\r\n */\n function FirstAidKit() {\n this.Id = null;\n this.Position = null;\n this.SealFound = null;\n this.SealLeft = null;\n this.IsEMK = false;\n }\n\n var service = {\n createNew: createNew,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n deleteFromList: deleteFromList\n };\n /**\r\n * Create a new FirstAidKit object \r\n * @memberof FirstAidKitFactory\r\n * @returns {object} FirstAidKit\r\n */\n\n function createNew() {\n return GenericModalFactory.createNew(FirstAidKit);\n }\n /**\r\n * Extend given FirstAidKit object \r\n * @memberof FirstAidKitFactory\r\n * @param {object} obj The FirstAidKit object that will be extended\r\n * @returns {object} FirstAidKit\r\n */\n\n\n function fromObject(obj) {\n return GenericModalFactory.fromObject(obj, FirstAidKit);\n }\n /**\r\n * Delete FirstAidKit object from given list\r\n * @memberof FirstAidKitFactory\r\n * @param {object} obj The FirstAidKit object that will be deleted\r\n * @returns {array} FirstAidKits\r\n */\n\n\n function deleteFromList(obj, objList) {\n return GenericModalFactory.deleteFromList(obj, objList);\n }\n /**\r\n * Extend given FirstAidKit object List \r\n * @memberof FirstAidKitFactory\r\n * @param {object} obj The FirstAidKit object that will be extended\r\n * @returns {array} FirstAidKits\r\n */\n\n\n function fromObjectList(objList) {\n return GenericModalFactory.fromObjectList(objList, FirstAidKit);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('FlightDetailCtrl', FlightDetailCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FlightDetailCtrl\r\n * @description \r\n * Manages the Flight Detail Modal View\r\n * @ngInject\r\n */\n\n function FlightDetailCtrl($scope, $uibModalInstance, ModalDialogResultFactory, CabinReportLocalEditFactory, AircraftTypeFactory, fd) {\n var result = ModalDialogResultFactory.createNew();\n result.Object = CabinReportLocalEditFactory.fromObject(fd);\n var reportAircraftTypes = new Array();\n var allAircraftTypes = AircraftTypeFactory.getAircraftTypesFromStorage();\n\n for (var c = 0; c < allAircraftTypes.length; c++) {\n reportAircraftTypes.push(allAircraftTypes[c].Code);\n }\n\n $scope.aircraftTypes = reportAircraftTypes;\n $scope.fd = result.Object;\n $scope.ok = ok;\n $scope.cancel = cancel;\n /**\r\n * Close modal after u check position\r\n * @memberof FlightDetailCtrl\r\n */\n\n function ok() {\n if (result.Object.AcType == null || result.Object.AcType == '') result.Object.AcType = '-';\n $uibModalInstance.close(result);\n }\n /**\r\n * Close Modal\r\n * @memberof FlightDetailCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('IncompleteServicesIssueCtrl', IncompleteServicesIssueCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name IncompleteServicesIssueCtrl\r\n * @description \r\n * Manages the Special Modal View\r\n * @ngInject\r\n */\n\n function IncompleteServicesIssueCtrl($scope, $uibModalInstance, ModalDialogResultFactory, IncompleteServicesIssueFactory, IncompleteServicesSourceFactory, service, fleetId) {\n // setup available reasons and services\n var a3Reasons = IncompleteServicesSourceFactory.getA3ReasonsFromStorage();\n var oaReasons = IncompleteServicesSourceFactory.getOAReasonsFromStorage();\n var a3Services = IncompleteServicesSourceFactory.getA3ServicesFromStorage();\n var oaServices = IncompleteServicesSourceFactory.getOAServicesFromStorage();\n if (!(a3Reasons instanceof Array)) a3Reasons = [];\n if (!(oaReasons instanceof Array)) oaReasons = [];\n if (!(a3Services instanceof Array)) a3Services = [];\n if (!(oaServices instanceof Array)) oaServices = [];\n\n if (fleetId == 1) {\n $scope.availableReasons = a3Reasons;\n $scope.availableServices = a3Services;\n } else {\n $scope.availableReasons = oaReasons;\n $scope.availableServices = oaServices;\n } //Both:\n // $scope.availableReasons = a3Reasons.concat(oaReasons).unique();\n // $scope.availableServices = a3Services.concat(oaServices).unique();\n\n\n var result = ModalDialogResultFactory.createNew();\n\n if (service == null) {\n result.Object = IncompleteServicesIssueFactory.createNew();\n result.isInsertMode = true;\n } else {\n result.Object = IncompleteServicesIssueFactory.fromObject(service);\n result.isInsertMode = false;\n }\n\n $scope.service = result.Object;\n $scope.service.ServiceClass = $scope.service.ServiceClass == null ? 'Y' : $scope.service.ServiceClass;\n $scope.ok = ok;\n $scope.cancel = cancel;\n $scope.clearIncompleteServiceRemarks = clearIncompleteServiceRemarks;\n $scope.addRows = addRows;\n $scope.removeRow = removeRow;\n\n function removeRow(index) {\n $scope.service.Rows.splice(index, 1);\n }\n\n function addRows() {\n var RowSet = {\n From: null,\n To: null\n };\n $scope.service.Rows.push(RowSet);\n }\n /**\r\n * Clear Field\r\n * @memberof IncompleteServicesIssueCtrl\r\n */\n\n\n function clearField(target, fieldName) {\n if (target[fieldName] == null || target[fieldName] == '') return false;\n bootbox.dialog({\n message: \"Please confirm that you wish to clear this field\",\n title: \"Attention\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n ok: {\n label: \"Ok\",\n className: \"btn-warning\",\n callback: function callback() {\n target[fieldName] = null;\n $scope.$apply();\n return true;\n }\n }\n }\n });\n }\n /**\r\n * Clear Special Meal Issue remarks\r\n * @memberof SpecialMealIssueCtrl\r\n */\n\n\n function clearIncompleteServiceRemarks(service) {\n clearField(service, \"Remarks\"); //sup.Remarks = null;\n }\n /**\r\n * set date and close modal\r\n * @memberof SpecialMealIssueCtrl\r\n */\n\n\n function ok() {\n var test = $scope.service;\n $uibModalInstance.close(result);\n }\n /**\r\n * Close modal after u check position\r\n * @memberof SpecialMealIssueCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('IncompleteServicesIssueFactory', IncompleteServicesIssueFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name IncompleteInFlightServicesFactory\r\n * @description \r\n * Manage Incomplete In-Flight Services Reasons.\r\n * @ngInject\r\n */\n\n function IncompleteServicesIssueFactory(GenericModalFactory) {\n var service = {\n createNew: createNew,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n deleteFromList: deleteFromList\n };\n /**\r\n * Initialiaze IncompleteService object \r\n * @memberof IncompleteInFlightServicesFactory\r\n */\n\n function IncompleteService() {\n this.Id = null;\n this.ServiceClass = null;\n this.Rows = [];\n this.ServiceType = null;\n this.Reason = null;\n this.Remarks = null;\n }\n /**\r\n * Create new IncompleteService object \r\n * @memberof IncompleteInFlightServicesFactory\r\n */\n\n\n function createNew() {\n var newObj = GenericModalFactory.createNew(IncompleteService);\n var RowSet = {\n From: null,\n To: null\n };\n newObj.Rows.push(RowSet);\n return newObj;\n }\n /**\r\n * Extend given IncompleteService object \r\n * @memberof IncompleteInFlightServicesFactory\r\n * @param {object} obj The IncompleteService object that will be extended\r\n * @returns {object} IncompleteService\r\n */\n\n\n function fromObject(obj) {\n return GenericModalFactory.fromObject(obj, IncompleteService);\n }\n /**\r\n * Delete IncompleteService object from given list\r\n * @memberof IncompleteInFlightServicesFactory\r\n * @param {object} obj The IncompleteService object that will be deleted\r\n * @returns {array} IncompleteServices\r\n */\n\n\n function deleteFromList(obj, objList) {\n return GenericModalFactory.deleteFromList(obj, objList);\n }\n /**\r\n * Extend given IncompleteService object List \r\n * @memberof IncompleteInFlightServicesFactory\r\n * @param {object} obj The IncompleteService object that will be extended\r\n * @returns {array} IncompleteServices\r\n */\n\n\n function fromObjectList(objList) {\n return GenericModalFactory.fromObjectList(objList, IncompleteService);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('IncompleteServicesSourceFactory', IncompleteServicesSourceFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name IncompleteInFlightServicesFactory\r\n * @description \r\n * Manage Incomplete In-Flight Services Reasons.\r\n * @ngInject\r\n */\n\n function IncompleteServicesSourceFactory(localStorageMD5Service) {\n var service = {\n setIncompleteInFlightServiceListOfValues: setIncompleteInFlightServiceListOfValues,\n getA3ReasonsFromStorage: getA3ReasonsFromStorage,\n getOAReasonsFromStorage: getOAReasonsFromStorage,\n getA3ServicesFromStorage: getA3ServicesFromStorage,\n getOAServicesFromStorage: getOAServicesFromStorage\n }; //Get From LocalStorage\n\n /**\r\n * Get all the Incomplete In-Flight Services Reasons for A3\r\n * @memberof IncompleteInFlightServicesFactory\r\n * @returns {array} TravelValueIncompleteReasons\r\n */\n\n function getA3ReasonsFromStorage() {\n var results = [];\n var listOfValues = localStorageMD5Service.get('incompleteInFlightServiceListOfValues');\n\n if (listOfValues) {\n var A3Reasons = listOfValues.filter(function (item) {\n return item.Fleet == \"A3\" && item.Type == \"Reason\";\n });\n results = A3Reasons.map(function (item) {\n return item.Value;\n });\n }\n\n return results;\n }\n /**\r\n * Get all the Incomplete In-Flight Services Reasons for OA\r\n * @memberof IncompleteInFlightServicesFactory\r\n * @returns {array} TravelValueIncompleteReasons\r\n */\n\n\n function getOAReasonsFromStorage() {\n var results = [];\n var listOfValues = localStorageMD5Service.get('incompleteInFlightServiceListOfValues');\n\n if (listOfValues) {\n var OAReasons = listOfValues.filter(function (item) {\n return item.Fleet == \"OA\" && item.Type == \"Reason\";\n });\n results = OAReasons.map(function (item) {\n return item.Value;\n });\n }\n\n return results;\n }\n /**\r\n * Get all the Incomplete In-Flight Services Types for A3\r\n * @memberof IncompleteInFlightServicesFactory\r\n * @returns {array} TravelValueIncompleteReasons\r\n */\n\n\n function getA3ServicesFromStorage() {\n var results = [];\n var listOfValues = localStorageMD5Service.get('incompleteInFlightServiceListOfValues');\n\n if (listOfValues) {\n var A3Services = listOfValues.filter(function (item) {\n return item.Fleet == \"A3\" && item.Type == \"ServiceType\";\n });\n results = A3Services.map(function (item) {\n return item.Value;\n });\n }\n\n return results;\n }\n /**\r\n * Get all the Incomplete In-Flight Services Types for OA\r\n * @memberof IncompleteInFlightServicesFactory\r\n * @returns {array} TravelValueIncompleteReasons\r\n */\n\n\n function getOAServicesFromStorage() {\n var results = [];\n var listOfValues = localStorageMD5Service.get('incompleteInFlightServiceListOfValues');\n\n if (listOfValues) {\n var A3Services = listOfValues.filter(function (item) {\n return item.Fleet == \"OA\" && item.Type == \"ServiceType\";\n });\n results = A3Services.map(function (item) {\n return item.Value;\n });\n }\n\n return results;\n } //Set to LocalStorage\n\n /**\r\n * Set all the Incomplete In-Flight Services List Of Values \r\n * @memberof IncompleteInFlightServicesFactory\r\n * @param {array} objects A list of IncompleteInFlightServicesFactory.\r\n */\n\n\n function setIncompleteInFlightServiceListOfValues(data) {\n localStorageMD5Service.set('incompleteInFlightServiceListOfValues', data);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('ItemPhotosCtrl', ItemPhotosCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ItemPhotosCtrl\r\n * @description \r\n * Manages the Item Photos Modal View\r\n * @ngInject\r\n */\n\n function ItemPhotosCtrl($scope, $uibModalInstance, PhotoFactory, item) {\n $scope.item = item;\n $scope.quality = 0.4;\n $scope.width = 1024;\n $scope.height = 768;\n $scope.comment = \"Recommended for printed documents with smaller font\";\n $scope.sizeLimitKb = 100;\n $scope.isImageTooLarge = isImageTooLarge;\n $scope.settingsSet = settingsSet;\n $scope.settingsName = settingsName;\n $scope.settingsText = settingsText;\n $scope.settings = 3;\n $scope.settingsMinus = settingsMinus;\n $scope.settingsPlus = settingsPlus;\n $scope.settingsDefault = settingsDefault;\n $scope.imageChanged = imageChanged;\n $scope.imageError = imageError;\n $scope.rotateImageLeft = rotateImageLeft;\n $scope.rotateImageRight = rotateImageRight;\n $scope.cancel = cancel;\n $scope.ok = ok;\n $scope.viewPhoto = viewPhoto;\n $scope.deletePhoto = deletePhoto;\n $scope.settingsText();\n /**\r\n * is Image Too Large \r\n * @memberof ItemPhotosCtrl\r\n */\n\n function isImageTooLarge() {\n var b = false;\n var i = $scope.item;\n\n if (i != null && i.Photos != null && i.Photos.length > 0 && i.Photos[0].PhotoData != null) {\n b = i.Photos[0].PhotoData.length > $scope.sizeLimitKb * 1024;\n }\n\n return b;\n }\n /**\r\n * Set settings\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function settingsSet() {\n if ($scope.settings == 0) {\n $scope.width = 320;\n $scope.height = 240;\n $scope.comment = \"Not recommended\";\n } else if ($scope.settings == 1) {\n $scope.width = 640;\n $scope.height = 480;\n $scope.comment = \"Recommended for objects/places\";\n } else if ($scope.settings == 2) {\n $scope.width = 800;\n $scope.height = 600;\n $scope.comment = \"Recommended for printed documents\";\n } else if ($scope.settings == 3) {\n $scope.width = 1024;\n $scope.height = 768;\n $scope.comment = \"Recommended for printed documents with smaller font\";\n } else if ($scope.settings == 4) {\n $scope.width = 1280;\n $scope.height = 1024;\n $scope.comment = \"Recommended for handwritten documents\";\n }\n }\n /**\r\n * Show settings name\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function settingsName() {\n if ($scope.settings == 0) return 'xsmall';else if ($scope.settings == 1) return 'small';else if ($scope.settings == 2) return 'normal';else if ($scope.settings == 3) return 'medium';else if ($scope.settings == 4) return 'high';else return 'High' + $scope.settings;\n }\n /**\r\n * Show settings text comment\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function settingsText() {\n return $scope.comment + \" (\" + $scope.width + 'x' + $scope.height + ' ' + $scope.quality + \")\";\n }\n /**\r\n * Lower image settings\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function settingsMinus() {\n $scope.settings--;\n if ($scope.settings < 0) $scope.settings = 0;\n $scope.settingsSet();\n }\n /**\r\n * Higher image settings\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function settingsPlus() {\n $scope.settings++;\n if ($scope.settings > 4) $scope.settings = 4;\n $scope.settingsSet();\n }\n /**\r\n * Set default image settings\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function settingsDefault() {\n $scope.settings = 2;\n $scope.settingsSet();\n }\n /**\r\n * Change Image settings\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function imageChanged(data) {\n //console.log('told of a new image', imageResult, this.imageBrowsed, $scope.imageBrowsed);\n var imageResult = data; //$scope.imageBrowsed;\n\n if (imageResult != null) {\n item.Photos = [];\n var img = PhotoFactory.createNew();\n img.PhotoData = imageResult.dataURL;\n img.FileType = imageResult.fileType || imageResult.file.type;\n item.Photos.push(img);\n $scope.filename = null;\n }\n }\n /**\r\n * Change Image settings\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function imageError(err) {\n console.log('told of an error', err);\n }\n /**\r\n * Rotate Image to the Left\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function rotateImageLeft(image) {\n var origImg = new Image();\n origImg.src = image.PhotoData;\n var oc = document.createElement('canvas');\n var octx = oc.getContext('2d');\n octx.mozImageSmoothingEnabled = false;\n octx.webkitImageSmoothingEnabled = false; // Inverse height and width as canvas size\n\n oc.width = origImg.height;\n oc.height = origImg.width; // Save original grid\n\n octx.save(); // Set origin of canvas to center | 0,0 is now w/2 and h/2\n\n octx.translate(Math.floor(origImg.height / 2), Math.floor(origImg.width / 2)); // Rotate the whole grid by X degrees\n\n octx.rotate(-1 * Math.PI / 2); // Draw the image into the rotated grid\n\n octx.drawImage(origImg, -Math.floor(origImg.width / 2), -Math.floor(origImg.height / 2), Math.floor(origImg.width), Math.floor(origImg.height)); // Restore grid coordinates\n\n octx.restore();\n image.PhotoData = oc.toDataURL('image/jpeg', $scope.quality);\n }\n /**\r\n * Rotate Image to the Left\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function rotateImageRight(image) {\n var origImg = new Image();\n origImg.src = image.PhotoData;\n var oc = document.createElement('canvas');\n var octx = oc.getContext('2d');\n octx.mozImageSmoothingEnabled = false;\n octx.webkitImageSmoothingEnabled = false; // Inverse height and width as canvas size\n\n oc.width = origImg.height;\n oc.height = origImg.width; // Save original grid\n\n octx.save(); // Set origin of canvas to center | 0,0 is now w/2 and h/2\n\n octx.translate(Math.floor(origImg.height / 2), Math.floor(origImg.width / 2)); // Rotate the whole grid by X degrees\n\n octx.rotate(Math.PI / 2); // Draw the image into the rotated grid\n\n octx.drawImage(origImg, -Math.floor(origImg.width / 2), -Math.floor(origImg.height / 2), Math.floor(origImg.width), Math.floor(origImg.height)); // Restore grid coordinates\n\n octx.restore();\n image.PhotoData = oc.toDataURL(image.FileType, $scope.quality);\n }\n /**\r\n * Close Modal\r\n * @memberof BarTrolleyCtrl\r\n */\n\n\n function ok() {\n $uibModalInstance.close();\n }\n /**\r\n * Close Modal\r\n * @memberof BarTrolleyCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close();\n }\n /**\r\n * View photo in new window\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function viewPhoto(pho) {\n window.open(pho.PhotoData);\n }\n /**\r\n * Delete photo\r\n * @memberof ItemPhotosCtrl\r\n */\n\n\n function deletePhoto(pho) {\n bootbox.dialog({\n message: \"Are you sure you want to delete this photo?\",\n title: \"Delete record\",\n buttons: {\n no: {\n label: \"No\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n yes: {\n label: \"Yes\",\n className: \"btn-warning\",\n callback: function callback() {\n PhotoFactory.deleteFromList(pho, item.Photos);\n $scope.$apply();\n }\n }\n }\n });\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('MedicalIncidentCtrl', MedicalIncidentCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name MedicalIncidentCtrl\r\n * @description \r\n * Manages the Medical Incident Modal View\r\n * @ngInject\r\n */\n\n function MedicalIncidentCtrl($scope, $timeout, $uibModalInstance, ModalDialogResultFactory, MedicalIncidentFactory, med) {\n $scope.clearField = clearField;\n $scope.clearMedicalRemarks = clearMedicalRemarks;\n $scope.clearMedicalSignature = clearMedicalSignature;\n $scope.ok = ok;\n $scope.cancel = cancel;\n var result = ModalDialogResultFactory.createNew();\n\n if (med == null) {\n result.Object = MedicalIncidentFactory.createNew();\n result.isInsertMode = true;\n } else {\n result.Object = MedicalIncidentFactory.fromObject(med);\n result.isInsertMode = false;\n }\n\n $scope.med = result.Object;\n $timeout(function () {\n $('.modal-medical').find('textarea').each(function (index, item) {\n if (item.value != '') autoAdjustTextarea(item);\n });\n }, 500);\n /**\r\n * Clear Field\r\n * @memberof MedicalIncidentCtrl\r\n */\n\n function clearField(target, fieldName) {\n if (target[fieldName] == null || target[fieldName] == '') return false;\n bootbox.dialog({\n message: \"Please confirm that you wish to clear this field\",\n title: \"Attention\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n ok: {\n label: \"Ok\",\n className: \"btn-warning\",\n callback: function callback() {\n target[fieldName] = null;\n $scope.$apply();\n return true;\n }\n }\n }\n });\n }\n /**\r\n * Clear medical remarks\r\n * @memberof MedicalIncidentCtrl\r\n */\n\n\n function clearMedicalRemarks(med) {\n $scope.clearField(med, \"Symptoms\");\n }\n /**\r\n * Clear medical signature function\r\n * @memberof MedicalIncidentCtrl\r\n */\n\n\n function clearMedicalSignature(med) {\n $scope.clearField(med, \"Signature\"); //med.Signature = null;\n }\n /**\r\n * Close modal after u check Name\r\n * @memberof MedicalIncidentCtrl\r\n */\n\n\n function ok() {\n if (result.Object.Name == null || result.Object.Name == '') result.Object.Name = '-';\n $uibModalInstance.close(result);\n }\n /**\r\n * Close modal\r\n * @memberof MedicalIncidentCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('MedicalIncidentFactory', MedicalIncidentFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name MedicalIncidentFactory\r\n * @description \r\n * Manage Report's MedicalIncindents.\r\n * @ngInject\r\n */\n\n function MedicalIncidentFactory(GenericModalFactory) {\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name MedicalIncidentFactory\r\n * @description \r\n * Manage Report's MedicalIncindents.\r\n * @ngInject\r\n */\n function MedicalIncident() {\n this.Id = null;\n this.FAKUsed = null;\n this.Medicine = null;\n this.Symptoms = null;\n this.Signature = null;\n this.Name = null;\n this.Phone = null;\n this.Email = null;\n this.DoctorInvolved = null;\n this.DoctorName = null;\n this.DoctorPhone = null;\n this.EMFAKUsed = null;\n }\n\n var service = {\n createNew: createNew,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n deleteFromList: deleteFromList\n };\n /**\r\n * Create a new MedicalIncident object \r\n * @memberof MedicalIncidentFactory\r\n * @returns {object} MedicalIncident\r\n */\n\n function createNew() {\n return GenericModalFactory.createNew(MedicalIncident);\n }\n /**\r\n * Create a new MedicalIncident object \r\n * @memberof MedicalIncidentFactory\r\n * @returns {object} MedicalIncident\r\n */\n\n\n function fromObject(obj) {\n return GenericModalFactory.fromObject(obj, MedicalIncident);\n }\n /**\r\n * Delete MedicalIncident object from given list\r\n * @memberof MedicalIncidentFactory\r\n * @param {object} obj The MedicalIncident object that will be deleted\r\n * @returns {array} MedicalIncindents\r\n */\n\n\n function deleteFromList(obj, objList) {\n return GenericModalFactory.deleteFromList(obj, objList);\n }\n /**\r\n * Extend given MedicalIncident object List \r\n * @memberof MedicalIncidentFactory\r\n * @param {object} obj The MedicalIncident object that will be extended\r\n * @returns {array} MedicalIncindents\r\n */\n\n\n function fromObjectList(objList) {\n return GenericModalFactory.fromObjectList(objList, MedicalIncident);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('OpenReportDialogCtrl', OpenReportDialogCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name OpenReportDialogCtrl\r\n * @description \r\n * Manages the open report modal functionality \r\n * @ngInject\r\n */\n\n function OpenReportDialogCtrl($scope, $uibModalInstance, $location, apiUrl, UserFactory, FlightFactory, CabinReportLocalEditFactory, flightId) {\n var user = UserFactory.getUser();\n var allServerReports = [];\n var flight = FlightFactory.getFlightFromStorage(flightId);\n if (flight == null) return; // load the reports\n\n var serverReportForThisUser = flight.getServerCabinReportForUser(user.aimsId);\n var serverReportsByAnotherUser = flight.getServerCabinReportsByAnotherUser(user.aimsId);\n var localReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId); // the user can create a new report only if there is not an existing one and\n // there is not a server report by him\n\n if (localReport != null || serverReportForThisUser != null) $scope.canCreateNewLocalReport = false;else $scope.canCreateNewLocalReport = true;\n\n if (serverReportForThisUser != null) {\n serverReportForThisUser.IsSameUser = \" (YOU)\";\n allServerReports.push(serverReportForThisUser);\n }\n\n for (var i = 0; i < serverReportsByAnotherUser.length; i++) {\n allServerReports.push(serverReportsByAnotherUser[i]);\n }\n\n $scope.localReport = localReport;\n $scope.serverReports = allServerReports;\n $scope.cancel = cancel;\n $scope.createNewLocalReport = createNewLocalReport;\n $scope.openLocalReport = openLocalReport;\n $scope.openServerReport = openServerReport;\n /**\r\n * Close Modal\r\n * @memberof OpenReportDialogCtrl\r\n */\n\n function cancel() {\n $uibModalInstance.dismiss('');\n }\n /**\r\n * Create new report and close modal\r\n * @memberof OpenReportDialogCtrl\r\n */\n\n\n function createNewLocalReport() {\n $location.path(\"report/new:\" + -1 + \"/\" + flightId);\n $uibModalInstance.dismiss('');\n }\n /**\r\n * Open Local Report\r\n * @memberof OpenReportDialogCtrl\r\n * @param {object} report\r\n */\n\n\n function openLocalReport(report) {\n $location.path(\"report/\" + report.ReportGuid);\n $uibModalInstance.dismiss('');\n }\n /**\r\n * Open Server stored Report\r\n * @memberof OpenReportDialogCtrl\r\n * @param {object} report\r\n */\n\n\n function openServerReport(report) {\n // get user token and send it as a parameter on the call\n var token = '';\n\n if (user != null) {\n token = user.token;\n token = encodeURIComponent(token);\n $location.path(\"reportsHistory/\" + report.ReportId + \"/\" + flightId + \"/Cabin\");\n }\n\n $uibModalInstance.dismiss('');\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('PhotoFactory', PhotoFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PhotoFactory\r\n * @description \r\n * Manage Report's Photos.\r\n * @ngInject\r\n */\n\n function PhotoFactory(GenericModalFactory) {\n /**\r\n * Initialiaze Photo object \r\n * @memberof PhotoFactory\r\n */\n function Photo() {\n this.Id = null;\n this.Remarks = null;\n this.RemarksShort = null;\n this.PhotoData = null;\n this.FileType = null;\n }\n\n var service = {\n createNew: createNew,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n deleteFromList: deleteFromList\n };\n /**\r\n * Create a new Photo object \r\n * @memberof PhotoFactory\r\n * @returns {object} Photo\r\n */\n\n function createNew() {\n return GenericModalFactory.createNew(Photo);\n }\n /**\r\n * Extend given Photo object \r\n * @memberof PhotoFactory\r\n * @param {object} obj The Photo object that will be extended\r\n * @returns {object} Photo\r\n */\n\n\n function fromObject(obj) {\n return GenericModalFactory.fromObject(obj, Photo);\n }\n /**\r\n * Delete Photo object from given list\r\n * @memberof PhotoFactory\r\n * @param {object} obj The Photo object that will be deleted\r\n * @returns {array} Photos\r\n */\n\n\n function deleteFromList(obj, objList) {\n return GenericModalFactory.deleteFromList(obj, objList);\n }\n /**\r\n * Extend given Photo object \r\n * @memberof PhotoFactory\r\n * @param {object} obj The Photo object that will be extended\r\n * @returns {object} Photo\r\n */\n\n\n function fromObjectList(objList) {\n return GenericModalFactory.fromObjectList(objList, Photo);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('SeatChangeCtrl', SeatChangeCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SeatChangeCtrl\r\n * @description \r\n * Manages the seat change Modal View\r\n * @ngInject\r\n */\n\n function SeatChangeCtrl(changedSeat, report, paxInfo, PaxInfoFactory, $scope, $uibModalInstance) {\n var paxInfo = paxInfo;\n var allPassengers = getPassengers();\n $scope.allPassengers = allPassengers;\n $scope.clearChangedSeatsRemarks = clearChangedSeatsRemarks;\n var result = {};\n\n if (changedSeat == null) {\n $scope.editMode = false;\n result.Object = null;\n result.isInsertMode = true;\n } else {\n $scope.editMode = true;\n result.Object = Object.assign({}, changedSeat);\n result.Object.check = true;\n result.isInsertMode = false;\n }\n\n $scope.changedSeat = result.Object;\n $scope.showSeatChangeWarning = false;\n $scope.showSeatChangeError = false;\n $scope.submitSeatChange = submitSeatChange;\n $scope.saveSeatChange = saveSeatChange;\n $scope.cancel = cancel;\n /**\r\n * Clear Field\r\n * @memberof SeatChangeCtrl\r\n */\n\n function clearField(target, fieldName) {\n if (target[fieldName] == null || target[fieldName] == '') return false;\n bootbox.dialog({\n message: \"Please confirm that you wish to clear this field\",\n title: \"Attention\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n ok: {\n label: \"Ok\",\n className: \"btn-warning\",\n callback: function callback() {\n target[fieldName] = null;\n $scope.$apply();\n return true;\n }\n }\n }\n });\n }\n /**\r\n * fix any input into 000A format\r\n * @memberof SeatChangeCtrl\r\n */\n\n\n function formatSeatInput() {\n var missingZeroes = 4 - $scope.changedSeat.NewSeatNo.length;\n\n for (var i = 0; i < missingZeroes; i++) {\n $scope.changedSeat.NewSeatNo = '0' + $scope.changedSeat.NewSeatNo;\n }\n }\n /**\r\n * Clear Seat Change remarks\r\n * @memberof SeatChangeCtrl\r\n * @param {object} changedSeat\r\n */\n\n\n function clearChangedSeatsRemarks(changedSeat) {\n clearField(changedSeat, \"Remarks\");\n }\n /**\r\n * Gets called when user hits submit. checks input then saves\r\n * @memberof SeatChangeCtrl\r\n */\n\n\n function submitSeatChange() {\n $scope.showSeatChangeError = false;\n\n if (!isSeatAvailable()) {\n return;\n }\n\n saveSeatChange();\n }\n /**\r\n * Save the new seat change to the report\r\n * @memberof SeatChangeCtrl\r\n */\n\n\n function saveSeatChange() {\n result.Object = $scope.changedSeat;\n\n for (var i = 0; i < allPassengers.length; i++) {\n if (allPassengers[i].SeatNo == result.Object.OriginalSeatNo) {\n result.Object.UCI = allPassengers[i].UCI;\n result.Object.PNR = allPassengers[i].PNR;\n result.Object.Name = allPassengers[i].Fullname;\n }\n }\n\n $uibModalInstance.close(result);\n }\n /**\r\n * Check if seat exists and is empty. fires warnings and errors\r\n * @memberof SeatChangeCtrl\r\n * @return {boolean} isSeatAvailable\r\n */\n\n\n function isSeatAvailable() {\n $scope.changedSeat.NewSeatNo = $scope.changedSeat.NewSeatNo.toUpperCase();\n formatSeatInput();\n\n if (paxInfo) {\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n if (paxInfo.Seatmap[i].Columns[j].SeatNo == $scope.changedSeat.NewSeatNo) {\n if (paxInfo.Seatmap[i].Columns[j].IsEmptySeat && !IsAlreadyGivenSeat($scope.changedSeat.NewSeatNo)) {\n return true;\n }\n\n $scope.showSeatChangeWarning = true;\n return false;\n }\n }\n }\n } //not found in seatmap\n\n\n $scope.showSeatChangeError = true;\n $scope.changedSeat.NewSeatNo = '';\n return false;\n }\n\n function IsAlreadyGivenSeat(newSeatNo) {\n return report.ChangedSeats.some(function (item) {\n return item.NewSeatNo == newSeatNo;\n });\n }\n /**\r\n * Close modal\r\n * @memberof SeatChangeCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n /**\r\n * Get all passengers and have not been changed already\r\n * @memberof SeatChangeCtrl\r\n * @return {array} passengers\r\n */\n\n\n function getPassengers() {\n var passengersList = [];\n\n if (paxInfo) {\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n var alreadyChanged = false;\n\n for (var k = 0; k < report.ChangedSeats.length; k++) {\n if (report.ChangedSeats[k].UCI == paxInfo.Seatmap[i].Columns[j].UCI && report.ChangedSeats[k].PNR == paxInfo.Seatmap[i].Columns[j].PNR && report.ChangedSeats[k].OriginalSeatNo == paxInfo.Seatmap[i].Columns[j].SeatNo) {\n alreadyChanged = true;\n }\n }\n\n if (!alreadyChanged && paxInfo.Seatmap[i].Columns[j].SeatNo && !paxInfo.Seatmap[i].Columns[j].IsEmptySeat) {\n passengersList.push(paxInfo.Seatmap[i].Columns[j]);\n }\n }\n }\n }\n\n return passengersList;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('ServerCabinReportFactory', ServerCabinReportFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ServerCabinReportFactory\r\n * @description \r\n * Manage Servers Cabin Reports\r\n * @ngInject\r\n */\n\n function ServerCabinReportFactory(GenericService) {\n /**\r\n * Initialiaze ServerCabinReport object \r\n * @memberof ServerCabinReportFactory\r\n */\n function ServerCabinReport() {\n this.AuthorAimsId = null;\n this.AuthorName = null;\n this.Created = null;\n this.FlightAimsId = null;\n this.FlightId = null;\n this.LastUpdated = null;\n this.ReportGuid = null;\n this.ReportId = null;\n this.ReportedItems = null;\n this.Source = null;\n this.getDescription = getDescription;\n this.isNothingToReport = isNothingToReport;\n }\n\n var objCallback = ServerCabinReport;\n var service = {\n fromObjectList: fromObjectList,\n constSourceLocalOwn: 'localOwn',\n constSourceLocalOther: 'localOther',\n constSourceStoredOwn: 'storedOwn',\n constSourceStoredOther: 'storedOther'\n };\n /**\r\n * Get ServerCabinReport Description\r\n * @memberof ServerCabinReportFactory\r\n * @returns {string} Description\r\n */\n\n function getDescription() {\n if (this.Created == null && this.AuthorName == null && this.ReportedItems == null) return '-null-';else return (this.AuthorAimsId || '?') + ' ' + (this.AuthorName || '?') + ' @ ' + (this.Created || '?') + (this.ReportedItems || 0) == 0 ? ' :: Nothing to report' : (this.ReportedItems || 0) + ' items logged';\n }\n /**\r\n * If there is something to report\r\n * @memberof ServerCabinReportFactory\r\n * @returns {bool} isNothingToReport\r\n */\n\n\n function isNothingToReport() {\n return (this.ReportedItems || 0) == 0;\n } //Factory Settings\n\n /**\r\n * Extend given ServerCabinReport object List \r\n * @memberof ServerCabinReportFactory\r\n * @param {object} obj The ServerCabinReport object that will be extended\r\n * @returns {array} ServerCabinReports\r\n */\n\n\n function fromObjectList(objList) {\n return GenericService.fromObjectList(objList, objCallback);\n }\n\n ;\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('SpecialMealIssueCtrl', SpecialMealIssueCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SpecialMealIssueCtrl\r\n * @description \r\n * Manages the Special Modal View\r\n * @ngInject\r\n */\n\n function SpecialMealIssueCtrl($scope, $timeout, $uibModalInstance, ModalDialogResultFactory, SpecialMealIssueFactory, SpecialMealTypeFactory, SpecialMealSourceFactory, smi) {\n // setup special meal types\n var smts = SpecialMealTypeFactory.getSpecialMealTypesFromStorageAsStrings();\n if (!(smts instanceof Array)) smts = [];\n $scope.specialMealTypes = smts; // setup datetime picker\n\n $scope.dateOptions = {\n formatYear: 'yyyy',\n startingDay: 1\n };\n $scope.opened = false;\n\n $scope.open = function ($event) {\n $event.preventDefault();\n $event.stopPropagation();\n $scope.opened = true;\n }; // setup special meal sources\n\n\n var smss = SpecialMealSourceFactory.getSpecialMealSourcesFromStorageAsStrings();\n if (!(smss instanceof Array)) smss = [];\n $scope.specialMealSources = smss;\n $scope.clearField = clearField;\n $scope.clearSpecialMealIssueRemarks = clearSpecialMealIssueRemarks;\n var result = ModalDialogResultFactory.createNew();\n\n if (smi == null) {\n result.Object = SpecialMealIssueFactory.createNew();\n result.isInsertMode = true;\n } else {\n result.Object = SpecialMealIssueFactory.fromObject(smi);\n\n if (smi.ReturnDate) {\n result.Object.ReturnDate = new Date(smi.ReturnDate);\n }\n\n result.isInsertMode = false;\n }\n\n $scope.smi = result.Object;\n $scope.ok = ok;\n $scope.cancel = cancel;\n $timeout(function () {\n $('.modal-special').find('textarea').each(function (index, item) {\n if (item.value != '') autoAdjustTextarea(item);\n });\n }, 500);\n /**\r\n * Clear Field\r\n * @memberof SpecialMealIssueCtrl\r\n */\n\n function clearField(target, fieldName) {\n if (target[fieldName] == null || target[fieldName] == '') return false;\n bootbox.dialog({\n message: \"Please confirm that you wish to clear this field\",\n title: \"Attention\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n ok: {\n label: \"Ok\",\n className: \"btn-warning\",\n callback: function callback() {\n target[fieldName] = null;\n $scope.$apply();\n return true;\n }\n }\n }\n });\n }\n /**\r\n * Clear Special Meal Issue remarks\r\n * @memberof SpecialMealIssueCtrl\r\n */\n\n\n function clearSpecialMealIssueRemarks(smi) {\n $scope.clearField(smi, \"Remarks\"); //sup.Remarks = null;\n }\n /**\r\n * set date and close modal\r\n * @memberof SpecialMealIssueCtrl\r\n */\n\n\n function ok() {\n if (result.Object.Name == null || result.Object.Name == '') result.Object.Name = '-';\n\n if ($scope.smi.ReturnDate != null) {\n var date = new Date($scope.smi.ReturnDate);\n var offset = date.getTimezoneOffset() / 60;\n var hours = date.getHours();\n date.setHours(hours - offset);\n result.Object.ReturnDate = date.toISOString();\n }\n\n $uibModalInstance.close(result);\n }\n /**\r\n * Close modal after u check position\r\n * @memberof SpecialMealIssueCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('SpecialMealIssueFactory', SpecialMealIssueFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SpecialMealIssueFactory\r\n * @description \r\n * Manage Report's SpecialMealIssues.\r\n * @ngInject\r\n */\n\n function SpecialMealIssueFactory(GenericModalFactory) {\n /**\r\n * Initialiaze SpecialMealIssue object \r\n * @memberof SpecialMealIssueFactory\r\n */\n function SpecialMealIssue() {\n this.Id = null;\n this.Name = null;\n this.Phone = null;\n this.Email = null;\n this.Source = null;\n this.MealType = null;\n this.ReturnDate = null;\n this.Remarks = null;\n }\n\n var service = {\n createNew: createNew,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n deleteFromList: deleteFromList\n };\n /**\r\n * Create new SpecialMealIssue object \r\n * @memberof SpecialMealIssueFactory\r\n */\n\n function createNew() {\n return GenericModalFactory.createNew(SpecialMealIssue);\n }\n\n ;\n /**\r\n * Extend given SpecialMealIssue object \r\n * @memberof SpecialMealIssueFactory\r\n * @param {object} obj The SpecialMealIssue object that will be extended\r\n * @returns {object} SpecialMealIssue\r\n */\n\n function fromObject(obj) {\n return GenericModalFactory.fromObject(obj, SpecialMealIssue);\n }\n /**\r\n * Delete SpecialMealIssue object from given list\r\n * @memberof SpecialMealIssueFactory\r\n * @param {object} obj The SpecialMealIssue object that will be deleted\r\n * @returns {array} SpecialMealIssues\r\n */\n\n\n function deleteFromList(obj, objList) {\n return GenericModalFactory.deleteFromList(obj, objList);\n }\n /**\r\n * Extend given SpecialMealIssue object List \r\n * @memberof SpecialMealIssueFactory\r\n * @param {object} obj The SpecialMealIssue object that will be extended\r\n * @returns {array} SpecialMealIssues\r\n */\n\n\n function fromObjectList(objList) {\n return GenericModalFactory.fromObjectList(objList, SpecialMealIssue);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('SpecialMealSourceFactory', SpecialMealSourceFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SpecialMealSourceFactory\r\n * @description \r\n * Manage Report's SpecialMealSources.\r\n * @ngInject\r\n */\n\n function SpecialMealSourceFactory(GenericValuesFactory) {\n /**\r\n * Initialiaze SpecialMealSource object \r\n * @memberof SpecialMealSourceFactory\r\n */\n function SpecialMealSource() {\n this.Code = null;\n }\n\n var callback = SpecialMealSource;\n var type = 'specialMealSources';\n var service = {\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n toObjectList: toObjectList,\n getSpecialMealSourcesFromStorage: getSpecialMealSourcesFromStorage,\n getSpecialMealSourcesFromStorageAsStrings: getSpecialMealSourcesFromStorageAsStrings,\n setSpecialMealSourcesToStorage: setSpecialMealSourcesToStorage\n };\n /**\r\n * Create a new SpecialMealSource object \r\n * @memberof SpecialMealSourceFactory\r\n * @returns {object} SpecialMealSource\r\n */\n\n function fromObject(obj) {\n return GenericValuesFactory.fromObject(obj, callback);\n }\n /**\r\n * Extend given SpecialMealSource object List \r\n * @memberof SpecialMealSourceFactory\r\n * @param {object} obj The SpecialMealSource object that will be extended\r\n * @returns {array} SpecialMealSources\r\n */\n\n\n function fromObjectList(objList) {\n return GenericValuesFactory.fromObjectList(objList, callback);\n }\n /**\r\n * Get all the SpecialMealSource's Code from given list\r\n * @memberof SpecialMealSourceFactory\r\n * @param {array} objectList An object list\r\n * @returns {array} SpecialMealSources\r\n */\n\n\n function toObjectList(objList) {\n return GenericValuesFactory.objList(objList);\n }\n /**\r\n * Get all the SpecialMealSource objects\r\n * @memberof SpecialMealSourceFactory\r\n * @returns {array} SpecialMealSources\r\n */\n\n\n function getSpecialMealSourcesFromStorage() {\n return GenericValuesFactory.getValuesFromStorage(callback, type);\n }\n /**\r\n * Get all the SpecialMealSource's codes\r\n * @memberof SpecialMealSourceFactory\r\n * @returns {array} SpecialMealSources\r\n */\n\n\n function getSpecialMealSourcesFromStorageAsStrings() {\n return GenericValuesFactory.getValuesFromStorageAsStrings(callback, type);\n }\n /**\r\n * Set all the SpecialMealSources\r\n * @memberof SpecialMealSourceFactory\r\n * @param {array} objects A list of SpecialMealSources.\r\n */\n\n\n function setSpecialMealSourcesToStorage(objList) {\n GenericValuesFactory.setValuesToStorage(objList, type);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('SpecialMealTypeFactory', SpecialMealTypeFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SpecialMealTypeFactory\r\n * @description \r\n * Manage SpecialMealTypes.\r\n * @ngInject\r\n */\n\n function SpecialMealTypeFactory(localStorageMD5Service) {\n /**\r\n * Initialiaze SpecialMealType object \r\n * @memberof SpecialMealTypeFactory\r\n */\n function SpecialMealType() {\n this.Code = null;\n }\n\n var callback = SpecialMealType;\n var type = 'specialMealTypes';\n var service = {\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n formObjects: formObjects,\n toObjectList: toObjectList,\n getSpecialMealTypesFromStorage: getSpecialMealTypesFromStorage,\n getSpecialMealTypesFromStorageAsStrings: getSpecialMealTypesFromStorageAsStrings,\n setSpecialMealTypesToStorage: setSpecialMealTypesToStorage,\n getSpecialMealTypesFromStorageAsObjects: getSpecialMealTypesFromStorageAsObjects\n };\n /**\r\n * Extend given SpecialMealType object \r\n * @memberof SpecialMealTypeFactory\r\n * @param {object} obj The SpecialMealType object that will be extended\r\n * @returns {object} SpecialMealType\r\n */\n\n function fromObject(obj) {\n if (obj == null) return null;\n var specialMealType = new SpecialMealType();\n specialMealType.Code = obj.code + ' - ' + obj.label;\n return specialMealType;\n }\n /**\r\n * Extend given SpecialMealType object list\r\n * @memberof SpecialMealTypeFactory\r\n * @param {array} objList The list of SpecialMealType objects that will be extended\r\n * @returns {object} SpecialMealTypes\r\n */\n\n\n function fromObjectList(objList) {\n if (objList == null) return null;\n var arrayLength = objList.length;\n var specialMealTypes = [];\n\n for (var i = 0; i < arrayLength; i++) {\n var specialMealType = new SpecialMealType();\n specialMealType.Code = objList[i].code + ' - ' + objList[i].label;\n specialMealTypes.push(specialMealType);\n }\n\n return specialMealTypes;\n }\n /**\r\n * Extend given SpecialMealType object list\r\n * @memberof SpecialMealTypeFactory\r\n * @param {array} objList The list of SpecialMealType objects that will be extended\r\n * @returns {object} SpecialMealTypes\r\n */\n\n\n function formObjects(objList) {\n if (objList == null) return null;\n var arrayLength = objList.length;\n var specialMealTypes = new Array();\n\n for (var i = 0; i < arrayLength; i++) {\n var specialMealType = new SpecialMealType();\n specialMealType.Code = objList[i].code;\n specialMealType.Label = objList[i].label;\n specialMealTypes.push(specialMealType);\n }\n\n return specialMealTypes;\n }\n /**\r\n * Get all the SpecialMealType's Code from given list\r\n * @memberof SpecialMealTypeFactory\r\n * @param {array} objectList An object list\r\n * @returns {array} SpecialMealTypes\r\n */\n\n\n function toObjectList(objList) {\n if (specialMealTypeList == null) return null;\n var arrayLength = specialMealTypeList.length;\n var objList = [];\n\n for (var i = 0; i < arrayLength; i++) {\n objList.push(specialMealTypeList[i].Code);\n }\n\n return objList;\n }\n /**\r\n * Get all the SpecialMealType objects\r\n * @memberof SpecialMealTypeFactory\r\n * @returns {array} SpecialMealTypes\r\n */\n\n\n function getSpecialMealTypesFromStorage() {\n var specialMealTypes = localStorageMD5Service.get('specialMealTypes');\n return fromObjectList(specialMealTypes);\n }\n /**\r\n * Get all the SpecialMealType full objects\r\n * @memberof SpecialMealTypeFactory\r\n * @returns {array} SpecialMealTypes\r\n */\n\n\n function getSpecialMealTypesFromStorageAsObjects() {\n var specialMealTypes = localStorageMD5Service.get('specialMealTypes');\n return formObjects(specialMealTypes);\n }\n /**\r\n * Get all the SpecialMealType's codes from local storage\r\n * @memberof SpecialMealTypeFactory\r\n * @returns {array} SpecialMealTypes\r\n */\n\n\n function getSpecialMealTypesFromStorageAsStrings() {\n var result = [];\n var objs = getSpecialMealTypesFromStorage();\n\n for (var i = 0; i < objs.length; i++) {\n result.push(objs[i].Code);\n }\n\n return result;\n }\n /**\r\n * Set all the SpecialMealTypes\r\n * @memberof SpecialMealTypeFactory\r\n * @param {array} objects A list of SpecialMealTypes.\r\n */\n\n\n function setSpecialMealTypesToStorage(specialMealTypes) {\n localStorageMD5Service.set('specialMealTypes', specialMealTypes);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('SupplyCtrl', SupplyCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SupplyCtrl\r\n * @description \r\n * Manages the Supply Modal View\r\n * @ngInject\r\n */\n\n function SupplyCtrl($scope, $timeout, $uibModalInstance, ModalDialogResultFactory, SupplyFactory, ACSupplyFactory, sup) {\n // setup supply types\n var smts = ACSupplyFactory.getACSuppliesFromStorageAsStrings();\n if (!(smts instanceof Array)) smts = [];\n $scope.supplyTypes = smts;\n $scope.clearField = clearField; // clear remarks function\n\n $scope.clearSupplyRemarks = clearSupplyRemarks;\n var result = ModalDialogResultFactory.createNew();\n\n if (sup == null) {\n result.Object = SupplyFactory.createNew();\n result.isInsertMode = true;\n } else {\n result.Object = SupplyFactory.fromObject(sup);\n result.isInsertMode = false;\n }\n\n $scope.sup = result.Object;\n $scope.ok = ok;\n $scope.cancel = cancel;\n $timeout(function () {\n $('.modal-supplies').find('textarea').each(function (index, item) {\n if (item.value != '') autoAdjustTextarea(item);\n });\n }, 500);\n /**\r\n * Clear Field\r\n * @memberof SupplyCtrl\r\n */\n\n function clearField(target, fieldName) {\n if (target[fieldName] == null || target[fieldName] == '') return false;\n bootbox.dialog({\n message: \"Please confirm that you wish to clear this field\",\n title: \"Attention\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n ok: {\n label: \"Ok\",\n className: \"btn-warning\",\n callback: function callback() {\n target[fieldName] = null;\n $scope.$apply();\n return true;\n }\n }\n }\n });\n }\n /**\r\n * Clear Supply Remarks\r\n * @memberof SupplyCtrl\r\n * @param {object} supply\r\n */\n\n\n function clearSupplyRemarks(sup) {\n $scope.clearField(sup, \"Remarks\"); //sup.Remarks = null;\n }\n /**\r\n * Close modal after u check SupplyType\r\n * @memberof SupplyCtrl\r\n */\n\n\n function ok() {\n if (result.Object.SupplyType == null || result.Object.SupplyType == '') result.Object.SupplyType = '-';\n $uibModalInstance.close(result);\n }\n /**\r\n * Close modal\r\n * @memberof SupplyCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('SupplyFactory', SupplyFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SupplyFactory\r\n * @description \r\n * Manage Report's Supplies.\r\n * @ngInject\r\n */\n\n function SupplyFactory(GenericModalFactory) {\n /**\r\n * Initialiaze a object \r\n * @memberof SupplyFactory\r\n */\n function Supply() {\n this.SupplyType = null;\n this.Remarks = null;\n }\n\n var service = {\n createNew: createNew,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n deleteFromList: deleteFromList\n };\n /**\r\n * Initialiaze Supply object \r\n * @memberof SupplyFactory\r\n */\n\n function createNew() {\n return GenericModalFactory.createNew(Supply);\n }\n /**\r\n * Extend given Supply object \r\n * @memberof SupplyFactory\r\n * @param {object} obj The Supply object that will be extended\r\n * @returns {object} Supply\r\n */\n\n\n function fromObject(obj) {\n return GenericModalFactory.fromObject(obj, Supply);\n }\n /**\r\n * Delete Supply object from given list\r\n * @memberof SupplyFactory\r\n * @param {object} obj The Supply object that will be deleted\r\n * @returns {array} Supplies\r\n */\n\n\n function deleteFromList(obj, objList) {\n return GenericModalFactory.deleteFromList(obj, objList);\n }\n /**\r\n * Extend given Supply object List \r\n * @memberof SupplyFactory\r\n * @param {object} obj The Supply object that will be extended\r\n * @returns {array} Supplies\r\n */\n\n\n function fromObjectList(objList) {\n return GenericModalFactory.fromObjectList(objList, Supply);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('TravelValueIncompleteReasonFactory', TravelValueIncompleteReasonFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name TravelValueIncompleteReasonFactory\r\n * @description \r\n * Manage Travel Value Incomplete Reasons.\r\n * @ngInject\r\n */\n\n function TravelValueIncompleteReasonFactory(localStorageMD5Service) {\n var service = {\n getReasonsFromStorage: getReasonsFromStorage,\n setReasonsToStorage: setReasonsToStorage\n };\n /**\r\n * Get all the Travel Value Incomplete Reasons full objects\r\n * @memberof TravelValueIncompleteReasonFactory\r\n * @returns {array} TravelValueIncompleteReasons\r\n */\n\n function getReasonsFromStorage() {\n var results = localStorageMD5Service.get('travelValueIncompleteReasons');\n return results || [];\n }\n /**\r\n * Set all the Travel Value Incomplete Reasons\r\n * @memberof TravelValueIncompleteReasonFactory\r\n * @param {array} objects A list of TravelValueIncompleteReasons.\r\n */\n\n\n function setReasonsToStorage(data) {\n localStorageMD5Service.set('travelValueIncompleteReasons', data);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('TravelValueSealCtrl', TravelValueSealCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name TravelValueSealCtrl\r\n * @description \r\n * Manages Travel Value Seal Modal View\r\n * @ngInject\r\n */\n\n function TravelValueSealCtrl($scope, $uibModalInstance, ModalDialogResultFactory, TravelValueSealFactory, tvs) {\n var result = ModalDialogResultFactory.createNew();\n\n if (tvs == null) {\n result.Object = TravelValueSealFactory.createNew();\n result.isInsertMode = true;\n } else {\n result.Object = TravelValueSealFactory.fromObject(tvs);\n result.isInsertMode = false;\n }\n\n $scope.tvs = result.Object;\n $scope.ok = ok;\n $scope.cancel = cancel;\n /**\r\n * Close modal after u check Label\r\n * @memberof TravelValueSealCtrl\r\n */\n\n function ok() {\n if (result.Object.Label == null || result.Object.Label == '') result.Object.Label = '-';\n $uibModalInstance.close(result);\n }\n /**\r\n * Close modal \r\n * @memberof TravelValueSealCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('TravelValueSealFactory', TravelValueSealFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name TravelValueSealFactory\r\n * @description \r\n * Manage Report's TravelValueSeals.\r\n * @ngInject\r\n */\n\n function TravelValueSealFactory(GenericModalFactory) {\n /**\r\n * Initialiaze TravelValueSeal object \r\n * @memberof TravelValueSealFactory\r\n */\n function TravelValueSeal() {\n this.Id = null;\n this.Position = null;\n this.SealFound = null;\n this.SealLeft = null;\n }\n\n var service = {\n createNew: createNew,\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n deleteFromList: deleteFromList\n };\n /**\r\n * Create new TravelValueSeal object \r\n * @memberof TravelValueSealFactory\r\n */\n\n function createNew() {\n return GenericModalFactory.createNew(TravelValueSeal);\n }\n /**\r\n * Extend given TravelValueSeal object \r\n * @memberof TravelValueSealFactory\r\n * @param {object} obj The TravelValueSeal object that will be extended\r\n * @returns {object} TravelValueSeal\r\n */\n\n\n function fromObject(obj) {\n return GenericModalFactory.fromObject(obj, TravelValueSeal);\n }\n /**\r\n * Delete TravelValueSeal object from given list\r\n * @memberof TravelValueSealFactory\r\n * @param {object} obj The TravelValueSeal object that will be deleted\r\n * @returns {array} TravelValueSeals\r\n */\n\n\n function deleteFromList(obj, objList) {\n return GenericModalFactory.deleteFromList(obj, objList);\n }\n /**\r\n * Extend given TravelValueSeal object List \r\n * @memberof TravelValueSealFactory\r\n * @param {object} obj The TravelValueSeal object that will be extended\r\n * @returns {array} TravelValueSeals\r\n */\n\n\n function fromObjectList(objList) {\n return GenericModalFactory.fromObjectList(objList, TravelValueSeal);\n }\n\n return service;\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.controller('UPGDCtrl', UPGDCtrl);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name UPGDCtrl\r\n * @description \r\n * Manages the UPGD Modal View\r\n * @ngInject\r\n */\n\n function UPGDCtrl(upgradedPassenger, report, paxInfo, PaxInfoFactory, $scope, $uibModalInstance) {\n // get eligible passengers\n var paxInfo = paxInfo;\n var eligiblePassengers = getEligiblePassengers();\n $scope.eligiblePassengers = eligiblePassengers;\n $scope.clearUPGDRemarks = clearUPGDRemarks;\n var result = {};\n\n if (upgradedPassenger == null) {\n $scope.editMode = false;\n result.Object = null;\n result.isInsertMode = true;\n } else {\n $scope.editMode = true;\n result.Object = Object.assign({}, upgradedPassenger);\n result.Object.check = true;\n result.isInsertMode = false;\n }\n\n $scope.upgradedPassenger = result.Object;\n $scope.showUpgradeWarning = false;\n $scope.showUpgradeError = false;\n $scope.submitUpgrade = submitUpgrade;\n $scope.saveUpgrade = saveUpgrade;\n $scope.cancel = cancel;\n /**\r\n * Clear Field\r\n * @memberof UPGDCtrl\r\n */\n\n function clearField(target, fieldName) {\n if (target[fieldName] == null || target[fieldName] == '') return false;\n bootbox.dialog({\n message: \"Please confirm that you wish to clear this field\",\n title: \"Attention\",\n buttons: {\n cancel: {\n label: \"Cancel\",\n className: \"btn-default\",\n callback: function callback() {}\n },\n ok: {\n label: \"Ok\",\n className: \"btn-warning\",\n callback: function callback() {\n target[fieldName] = null;\n $scope.$apply();\n return true;\n }\n }\n }\n });\n }\n /**\r\n * fix any input into 000A format\r\n * @memberof UPGDCtrl\r\n */\n\n\n function formatSeatInput() {\n var missingZeroes = 4 - $scope.upgradedPassenger.UpgradedSeatNo.length;\n\n for (var i = 0; i < missingZeroes; i++) {\n $scope.upgradedPassenger.UpgradedSeatNo = '0' + $scope.upgradedPassenger.UpgradedSeatNo;\n }\n }\n /**\r\n * Clear upgrade remarks\r\n * @memberof UPGDCtrl\r\n * @param {object} upgradedPassenger\r\n */\n\n\n function clearUPGDRemarks(upgradedPassenger) {\n clearField(upgradedPassenger, \"Remarks\");\n }\n /**\r\n * Gets called when user hits submit. checks input then saves\r\n * @memberof UPGDCtrl\r\n */\n\n\n function submitUpgrade() {\n $scope.showUpgradeError = false;\n\n if (!isSeatAvailable()) {\n return;\n }\n\n saveUpgrade();\n }\n /**\r\n * Save the new upgrade to the report\r\n * @memberof UPGDCtrl\r\n */\n\n\n function saveUpgrade() {\n result.Object = $scope.upgradedPassenger;\n\n for (var i = 0; i < eligiblePassengers.length; i++) {\n if (eligiblePassengers[i].SeatNo == result.Object.OriginalSeatNo) {\n result.Object.UCI = eligiblePassengers[i].UCI;\n result.Object.PNR = eligiblePassengers[i].PNR;\n }\n }\n\n $uibModalInstance.close(result);\n }\n /**\r\n * Check if seat exists and is empty. fires warnings and errors\r\n * @memberof UPGDCtrl\r\n * @return {boolean} isSeatAvailable\r\n */\n\n\n function isSeatAvailable() {\n $scope.upgradedPassenger.UpgradedSeatNo = $scope.upgradedPassenger.UpgradedSeatNo.toUpperCase();\n formatSeatInput();\n\n if (paxInfo) {\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n if (paxInfo.Seatmap[i].Columns[j].SeatNo == $scope.upgradedPassenger.UpgradedSeatNo) {\n if (paxInfo.Seatmap[i].Columns[j].IsEmptySeat) {\n return true;\n }\n\n $scope.showUpgradeWarning = true;\n return false;\n }\n }\n }\n } //not found in seatmap\n\n\n $scope.showUpgradeError = true;\n $scope.upgradedPassenger.UpgradedSeatNo = '';\n return false;\n }\n /**\r\n * Close modal\r\n * @memberof UPGDCtrl\r\n */\n\n\n function cancel() {\n $uibModalInstance.close(null);\n }\n /**\r\n * Get all passengers that are eligible for upgrade, are in Y cabin and have not been upgraded already\r\n * @memberof UPGDCtrl\r\n * @return {array} eligiblePassengers\r\n */\n\n\n function getEligiblePassengers() {\n var eligiblePassengersList = [];\n\n if (paxInfo) {\n for (var i = 0; i < paxInfo.Seatmap.length; i++) {\n for (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\n if (paxInfo.Seatmap[i].Columns[j].IsEligibleForUpgrade && paxInfo.Seatmap[i].Columns[j].Cabin == 'Y') {\n var alreadyUpgraded = false;\n\n for (var k = 0; k < report.UpgradedPassengers.length; k++) {\n if (report.UpgradedPassengers[k].UCI == paxInfo.Seatmap[i].Columns[j].UCI && report.UpgradedPassengers[k].PNR == paxInfo.Seatmap[i].Columns[j].PNR && report.UpgradedPassengers[k].OriginalSeatNo == paxInfo.Seatmap[i].Columns[j].SeatNo) {\n alreadyUpgraded = true;\n }\n }\n\n if (!alreadyUpgraded) {\n eligiblePassengersList.push(paxInfo.Seatmap[i].Columns[j]);\n }\n }\n }\n }\n }\n\n return eligiblePassengersList;\n }\n }\n})();\n\"use strict\";\n\n(function () {\n 'use strict';\n\n a3_cabin_reports.factory('WaterUpliftActionFactory', WaterUpliftActionFactory);\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name WaterUpliftActionFactory\r\n * @description \r\n * Manage Water Uplift Actions.\r\n * @ngInject\r\n */\n\n function WaterUpliftActionFactory(GenericValuesFactory) {\n /**\r\n * Initialiaze WaterUpliftAction object \r\n * @memberof WaterUpliftActionFactory\r\n */\n function WaterUpliftAction() {\n this.Code = null;\n }\n\n var callback = WaterUpliftAction;\n var type = 'waterUpliftActions';\n var service = {\n fromObject: fromObject,\n fromObjectList: fromObjectList,\n toObjectList: toObjectList,\n getWaterUpliftActionsFromStorageAsStrings: getWaterUpliftActionsFromStorageAsStrings,\n setWaterUpliftActionsToStorage: setWaterUpliftActionsToStorage\n };\n /**\r\n * Extend given WaterUpliftAction object \r\n * @memberof WaterUpliftActionFactory\r\n * @param {object} obj The WaterUpliftAction object that will be extended\r\n * @returns {object} WaterUpliftAction\r\n */\n\n function fromObject(obj) {\n return GenericValuesFactory.fromObject(obj, callback);\n }\n\n ;\n /**\r\n * Extend given WaterUpliftAction object \r\n * @memberof WaterUpliftActionFactory\r\n * @param {object} obj The WaterUpliftAction object that will be extended\r\n * @returns {object} WaterUpliftAction\r\n */\n\n function fromObjectList(objList) {\n return GenericValuesFactory.fromObjectList(objList, callback);\n }\n\n ;\n /**\r\n * Get all the WaterUpliftAction's Code from given list\r\n * @memberof WaterUpliftActionFactory\r\n * @param {array} objectList An object list\r\n * @returns {array} WaterUpliftActions\r\n */\n\n function toObjectList(objList) {\n return GenericValuesFactory.objList(objList);\n }\n\n ;\n /**\r\n * Get all the WaterUpliftAction's codes from local storage\r\n * @memberof WaterUpliftActionFactory\r\n * @returns {array} WaterUpliftActions\r\n */\n\n function getWaterUpliftActionsFromStorageAsStrings() {\n return GenericValuesFactory.getValuesFromStorageAsStrings(callback, type);\n }\n /**\r\n * Get all the WaterUpliftAction's codes from local storage\r\n * @memberof WaterUpliftActionFactory\r\n * @returns {array} WaterUpliftActions\r\n */\n\n\n function setWaterUpliftActionsToStorage(objList) {\n GenericValuesFactory.setValuesToStorage(objList, type);\n }\n\n return service;\n }\n})();","//***Modal Dialog for Application Updates - non angular **/\r\nvar modalUpdates;\r\nvar isDownloanding = false;\r\nvar isCheckForUpdate = false;\r\n\r\n(function() {\r\n\r\n if ('applicationCache' in window && !('serviceWorker' in navigator)) {\r\n modalUpdates = $('.modal-updating').modal({\r\n backdrop: 'static',\r\n keyboard: true,\r\n show: false\r\n });\r\n modalUpdates.show = function() {\r\n modalUpdates.removeClass('update-success');\r\n modalUpdates.find('.progress').show();\r\n modalUpdates.find('.message-success').hide();\r\n modalUpdates.find('.message-danger').hide();\r\n modalUpdates.find('.message-no-update').hide();\r\n modalUpdates.find('.btn-update-retry').hide();\r\n modalUpdates.find('.btn-update-close').hide();\r\n modalUpdates.find('.btn-update-ok').hide();\r\n $('.modal-dialog').modal('hide');\r\n modalUpdates.modal('show');\r\n }\r\n modalUpdates.hide = function() {\r\n modalUpdates.modal('hide');\r\n }\r\n modalUpdates.success = function() {\r\n modalUpdates.show();\r\n modalUpdates.find('.progress').hide();\r\n modalUpdates.find('.message-success').show();\r\n modalUpdates.find('.message-danger').hide();\r\n modalUpdates.find('.message-no-update').hide();\r\n modalUpdates.find('.btn-update-retry').hide();\r\n modalUpdates.find('.btn-update-close').hide();\r\n modalUpdates.find('.btn-update-ok').show();\r\n modalUpdates.addClass('update-success');\r\n setTimeout(function() {\r\n modalUpdates.modal('hide');\r\n }, 2000);\r\n }\r\n modalUpdates.noUpdate = function() {\r\n modalUpdates.show();\r\n modalUpdates.find('.progress').hide();\r\n modalUpdates.find('.message-success').hide();\r\n modalUpdates.find('.message-danger').hide();\r\n modalUpdates.find('.message-no-update').show();\r\n modalUpdates.find('.btn-update-retry').hide();\r\n modalUpdates.find('.btn-update-close').hide();\r\n modalUpdates.find('.btn-update-ok').show();\r\n isCheckForUpdate = false;\r\n }\r\n\r\n modalUpdates.failure = function(errorMessage) {\r\n modalUpdates.show();\r\n modalUpdates.find('.progress').hide();\r\n modalUpdates.find('.message-success').hide();\r\n modalUpdates.find('.message-danger').show();\r\n modalUpdates.find('.message-no-update').hide();\r\n modalUpdates.find('.btn-update-retry').show();\r\n modalUpdates.find('.btn-update-close').show();\r\n modalUpdates.find('.btn-update-ok').hide();\r\n //setTimeout(function(){location.reload();}, 2000);\r\n if (errorMessage && errorMessage != '') {\r\n modalUpdates.find('.update-error').text(errorMessage);\r\n } else {\r\n modalUpdates.find('.update-error').text('');\r\n }\r\n }\r\n modalUpdates.on('hidden.bs.modal', function(e) {\r\n var b = modalUpdates.hasClass('update-success');\r\n if (b) location.reload(true);\r\n })\r\n }\r\n\r\n}).call(this);\r\n\r\n\r\n//** ApplicationCache Events & Actions **//\r\n(function() {\r\n ////////////////////////////////////////////////////index scripts (cache)////////////////////////////////////////////////////\r\n if ('applicationCache' in window && !('serviceWorker' in navigator)) {\r\n // Convenience array of status values\r\n\r\n var cacheHandler = function() {}\r\n\r\n cacheHandler.cacheStatusValues = [];\r\n cacheHandler.cacheStatusValues[0] = 'uncached';\r\n cacheHandler.cacheStatusValues[1] = 'idle';\r\n cacheHandler.cacheStatusValues[2] = 'checking';\r\n cacheHandler.cacheStatusValues[3] = 'downloading';\r\n cacheHandler.cacheStatusValues[4] = 'updateready';\r\n cacheHandler.cacheStatusValues[5] = 'obsolete';\r\n\r\n cacheHandler.onDownloading = function(e) {\r\n isDownloanding = true;\r\n modalUpdates.show();\r\n cacheHandler.logEvent(e);\r\n }\r\n cacheHandler.onCached = function(e) {\r\n modalUpdates.hide();\r\n cacheHandler.logEvent(e);\r\n }\r\n cacheHandler.onChecking = function(e) {\r\n //ShowWaitDialog();\r\n cacheHandler.logEvent(e);\r\n }\r\n cacheHandler.onProgress = function(e) {}\r\n cacheHandler.onObsolete = function(e) {}\r\n cacheHandler.onError = function(e) {\r\n //debugger;\r\n var message = \"Could not download application updates due to an unexpected error.\\n\" +\r\n \"make sure that cache.manifest is being served with MIME type: text/cache-manifest\";\r\n //actual error message if any\r\n if (e.message) message = e.message;\r\n console.error(message);\r\n //hide update dialog if visible\r\n if (isDownloanding) {\r\n modalUpdates.failure(message);\r\n } else {\r\n modalUpdates.hide();\r\n }\r\n }\r\n cacheHandler.onNoUpdate = function(e) {\r\n if (isCheckForUpdate) {\r\n modalUpdates.noUpdate();\r\n } else {\r\n modalUpdates.hide();\r\n }\r\n isDownloanding = false;\r\n cacheHandler.logEvent(e);\r\n }\r\n cacheHandler.onUpdateReady = function(e) {\r\n try {\r\n cache.swapCache();\r\n } catch (e) {}\r\n cacheHandler.logEvent(e);\r\n isDownloanding = false;\r\n modalUpdates.success();\r\n //location.reload(true);\r\n }\r\n // Log every event to the console\r\n cacheHandler.logEvent = function(e) {\r\n // var status, type, message; //online,\r\n // //online = (navigator.online) ? 'yes' : 'no';\r\n // status = cacheHandler.cacheStatusValues[cache.status];\r\n // type = e.type;\r\n // message = '';//'online: ' + online;\r\n // message += 'CACHE: event: ' + type;\r\n // message += ', status: ' + status;\r\n // if (type == 'error' && navigator.online) {\r\n // message += ' (prolly a syntax error in manifest)';\r\n // }\r\n // console.log(message);\r\n }\r\n\r\n var cache = window.applicationCache;\r\n cache.addEventListener('cached', cacheHandler.onCached, false);\r\n cache.addEventListener('checking', cacheHandler.onChecking, false);\r\n cache.addEventListener('downloading', cacheHandler.onDownloading, false);\r\n cache.addEventListener('error', cacheHandler.onError, false);\r\n //cache.addEventListener('error', cacheHandler.logEvent, false);\r\n cache.addEventListener('noupdate', cacheHandler.onNoUpdate, false);\r\n cache.addEventListener('obsolete', cacheHandler.onObsolete, false);\r\n cache.addEventListener('progress', cacheHandler.onProgress, false);\r\n cache.addEventListener('updateready', cacheHandler.onUpdateReady, false);\r\n }\r\n\r\n $('#update-error-btn').click(function() {\r\n var alert = $('.hidden-update-error');\r\n if (alert.hasClass('hidden')) {\r\n alert.removeClass('hidden');\r\n $('#update-error-btn').text(\"show less\");\r\n } else {\r\n alert.addClass('hidden');\r\n $('#update-error-btn').text(\"show more\");\r\n }\r\n });\r\n\r\n $('body').on('click', '#update-check-btn', function() {\r\n isCheckForUpdate = true;\r\n var url = location.origin;\r\n $.ajax({\r\n type: \"GET\",\r\n url: url,\r\n cache: false,\r\n success: function() {\r\n //get cache\r\n var cache = window.applicationCache;\r\n // Update the user's cache\r\n if (cache != null && cache != undefined && (cache.status == 1 || cache.status > 3)) {\r\n cache.update();\r\n }\r\n }\r\n /*,\r\n error: function(){\r\n console.log('error');\r\n }*/\r\n });\r\n });\r\n\r\n}).call(this);\r\n\r\n$(document).on( \"keydown\",'.modal textarea', function(e) {\r\n \r\n var zIndex = $(this).parents('.modal').css('z-index');\r\n if(zIndex){\r\n $(this).parents('.modal').css('z-index',zIndex+1);\r\n $(this).parents('.modal').css('z-index',zIndex)\r\n }\r\n});","$(function () {\r\n\tangular.bootstrap(document, ['a3.cabin.reports']);\r\n});\r\n\t\t\r\nvar a3_cabin_reports = angular.module('a3.cabin.reports', [ \r\n //angular modules\r\n 'ngSanitize', \r\n 'ngRoute', \r\n 'ngTouch',\r\n \r\n //3rd party modules\r\n 'angular-md5',\r\n\t'LocalStorageModule', \r\n 'ui.bootstrap',\r\n 'nya.bootstrap.select',\r\n 'ui.toggle',\r\n 'ui.sortable',\r\n\r\n //Our modules\r\n 'MyDirectives',\r\n 'LocalStorageMD5Module'\r\n\r\n]);\r\n\r\n \r\n\r\n\r\n\r\n\r\n","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.controller('AssignmentModalCtrl', AssignmentModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name AssignmentModalCtrl\r\n * @description \r\n * Manages the Assignment Modal\r\n * @ngInject\r\n */\r\n\tfunction AssignmentModalCtrl($scope, assignment, info, $uibModalInstance, CampaignFactory) {\r\n\t\t\r\n\t\t$scope.assignment = JSON.parse(JSON.stringify(assignment));\r\n\t\t$scope.info = info;\r\n\t\t$scope.cancel = cancel;\r\n\t\t$scope.submit = submit;\r\n\t\t$scope.giftStatus = CampaignFactory.giftStatusList();\r\n\r\n /**\r\n * Close the modal\r\n * @memberof AssignmentModalCtrl\r\n */\r\n\t\tfunction cancel() {\r\n\t\t\t$uibModalInstance.dismiss('close');\r\n\t\t}\r\n\r\n\t\tfunction submit() {\r\n\t\t\tCampaignFactory.updateCampaignPassenger(info.flightId, $scope.assignment);\r\n\t\t\t$uibModalInstance.close('close');\r\n\t\t}\r\n\t}\r\n\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\n// setup routing\r\na3_cabin_reports.config(routeConfig);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name routeConfig\r\n * @description \r\n * Route configuration\r\n * @ngInject\r\n */ \r\n function routeConfig($routeProvider) {\r\n\t$routeProvider\r\n\t\t.when('/', {\r\n\t\t\tcontroller: 'CalendarCtrl',\r\n\t\t\ttemplateUrl: 'views/calendar.html'\r\n\t\t})\r\n\t\t.when('/login', {\r\n\t\t\tcontroller: 'LoginCtrl',\r\n\t\t\ttemplateUrl: 'views/login.html'\r\n\t\t})\r\n\t\t.when('/flightinfo/:flightId', {\r\n\t\t\tcontroller: 'FlightInfoCtrl',\r\n\t\t\ttemplateUrl: 'views/flight-info.html',\r\n reloadOnSearch: false\r\n\t\t})\r\n\t\t.when('/selectedflightinfo/:flightId/:flightDate/:flightNo/:departure', {\r\n\t\t\tcontroller: 'SelectedFlightCtrl',\r\n\t\t\ttemplateUrl: 'views/SearchFlights/selected-flight-info.html',\r\n reloadOnSearch: false\r\n\t\t})\r\n .when('/leaverequest', {\r\n controller: 'LeaveRequestCtrl',\r\n templateUrl: 'views/LeaveRequest/leaveRequest.html'\r\n })\r\n\t\t.when('/pax/:flightId', {\r\n\t\t\tcontroller: 'PaxCtrl',\r\n\t\t\ttemplateUrl: 'views/pax.html'\r\n\t\t})\r\n\t\t.when('/report/:reportId/', {\r\n\t\t\tcontroller: 'ReportCtrl',\r\n\t\t\ttemplateUrl: 'views/report.html'\r\n\t\t})\r\n\t\t.when('/report/:reportId/:flightId', {\r\n\t\t\tcontroller: 'ReportCtrl',\r\n\t\t\ttemplateUrl: 'views/report.html'\r\n\t\t})\r\n\t\t.when('/pdf/:reportId', {\r\n\t\t\tcontroller: 'ReportCtrl',\r\n\t\t\ttemplateUrl: 'views/report.html'\r\n\t\t})\r\n\t\t.when('/reset', {\r\n\t\t\tcontroller: 'ResetDeviceCtrl',\r\n\t\t\ttemplateUrl: 'views/reset.html'\r\n\t\t})\r\n\t\t.when('/debug', {\r\n\t\t\tcontroller: 'DebugCtrl',\r\n\t\t\ttemplateUrl: 'views/debug.html'\r\n\t\t})\r\n\t\t.when('/assessment/:flightId', {\r\n\t\t\tcontroller: 'AssessmentCtrl',\r\n\t\t\ttemplateUrl: 'views/assessment.html'\r\n\t\t})\r\n\t\t.when('/faqs', {\r\n\t\t\tcontroller: 'FaqsCtrl',\r\n\t\t\ttemplateUrl: 'views/faqs.html'\r\n\t\t})\r\n\t\t.when('/rosterRequests', {\r\n\t\t\tcontroller: 'RequestsCtrl',\r\n\t\t\ttemplateUrl: 'views/RosterRequests/requests.html'\r\n\t\t})\r\n\t\t.when('/memos/:filter', {\r\n\t\t\tcontroller: 'MemosCtrl',\r\n\t\t\ttemplateUrl: 'views/memos.html'\r\n\t\t})\r\n\t\t.when('/memos', {\r\n\t\t\tcontroller: 'MemosCtrl',\r\n\t\t\ttemplateUrl: 'views/memos.html'\r\n\t\t})\r\n\t\t.when('/messages/:flightId', {\r\n\t\t\tcontroller: 'MessageCtrl',\r\n\t\t\ttemplateUrl: 'views/messages.html'\r\n\t\t})\r\n\t\t.when('/messages/', {\r\n\t\t\tcontroller: 'MessageCtrl',\r\n\t\t\ttemplateUrl: 'views/messages.html'\r\n\t\t})\r\n .when('/ticket', {\r\n\t\t\tcontroller: 'TicketCtrl',\r\n\t\t\ttemplateUrl: 'views/ticket.html'\r\n\t\t})\r\n\t\t.when('/bucket', {\r\n controller: 'BucketCtrl',\r\n templateUrl: 'views/Bucket/bucketCalendar.html'\r\n })\r\n\t\t.when('/bucketDay/:dutyId', {\r\n controller: 'BucketDayCtrl',\r\n templateUrl: 'views/Bucket/bucketDay.html'\r\n\t\t})\r\n\t\t.when('/groundDuty/:groundDutyId', {\r\n controller: 'GroundDutyCtrl',\r\n templateUrl: 'views/GroundDuty/groundDuty-info.html'\r\n\t\t})\r\n\t\t.when('/crewRoute/:dutyNo/:dutyDay', {\r\n\t\t\tcontroller: 'CrewRouteCtrl',\r\n\t\t\ttemplateUrl: 'views/CrewRoute/crew-route-info.html',\r\n\t\t})\r\n\t\t.when('/reportsHistory/:reportId/:flightId/:reportType', {\r\n\t\t\tcontroller: 'ReportsHistoryCtrl',\r\n\t\t\ttemplateUrl: 'views/reportsHistory.html'\r\n\t\t})\r\n\t\t .when('/flightcourse/:courseId/:dutyNo/:dutyDay/:date',{\r\n controller: 'FlightCourseCtrl',\r\n\t\t\ttemplateUrl: 'views/Training/flightCourse.html'\r\n\t\t})\r\n\t\t.when('/flightcourse/:courseId/:dutyNo/:dutyDay/:date/:flightId',{\r\n controller: 'FlightCourseCtrl',\r\n\t\t\ttemplateUrl: 'views/Training/flightCourse.html'\r\n\t\t})\r\n\t\t.when('/groundcourse/:courseId/:dutyId/:date',{\r\n controller: 'GroundCourseCtrl',\r\n\t\t\ttemplateUrl: 'views/Training/groundCourse.html'\r\n })\r\n\t\t.when('/safetyreport/cabincrewreport/:flightId',{\r\n\t\t\tcontroller: 'SafetyCtrl',\r\n\t\t\ttemplateUrl: 'views/Safety/cabinCrewReport.html'\r\n\t\t})\r\n\t\t.when('/safetyreport/fatiguereport/:flightId',{\r\n\t\t\tcontroller: 'FatigueCtrl',\r\n\t\t\ttemplateUrl: 'views/Safety/fatigueReport.html'\r\n\t\t})\r\n\t\t.when('/groundHistory/:courseId/:dutyId/:date/:phaseId',{\r\n\t\t\tcontroller: 'ModuleHistoryCtrl',\r\n\t\t\ttemplateUrl: 'views/Training/moduleHistory.html'\r\n\t\t})\r\n\t\t.when('/flightHistory/:courseId/:dutyNo/:dutyDay/:date/:phaseId',{\r\n\t\t\tcontroller: 'ModuleHistoryCtrl',\r\n\t\t\ttemplateUrl: 'views/Training/moduleHistory.html'\r\n\t\t})\r\n\t\t.when('/traineecourse/:traineeCourseId/:dutyId/:date',{\r\n\t\t\tcontroller: 'TraineeCourseCtrl',\r\n\t\t\ttemplateUrl: 'views/TraineeCourse/trainee-course.tpl.html'\r\n\t\t})\r\n\t\t.when('/mealLibrary', {\r\n\t\t\tcontroller: 'PassengerMealsCtrl',\r\n\t\t\ttemplateUrl: 'views/PassengerMealsInfo/mealsLibrary.html'\r\n\t\t})\r\n\t\t.otherwise({\r\n\t\t\tredirectTo: '/'\r\n\t\t})\r\n }\r\n \r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\n\r\na3_cabin_reports.run(runBlock);\r\n\r\n/* @ngInject */ \r\nfunction runBlock($rootScope, $timeout, $location,$anchorScroll, UserFactory, UserTokenFactory,$templateCache,SettingsMain, SWUpdateService,\r\n CabinReportLocalEditFactory,CrewAssessmentFactory,PaxInfoFactory,LogService) {\r\n //make sure that each route change validates that the user is still logged in\r\n var valid = ['/login', '/reset', '/debug','/ticket'];\r\n $rootScope.$on('$routeChangeStart', function(event, next, current) {\r\n if (valid.indexOf($location.$$path) < 0 && !UserFactory.isLoggedIn()) {\r\n event.preventDefault();\r\n $location.path('/login');\r\n }\r\n \r\n //START - SERVICE WORKERS\r\n if ('serviceWorker' in navigator) {\r\n SWUpdateService.initialize();\r\n\r\n navigator.serviceWorker.getRegistration().then(function(registration) {\r\n $rootScope.SWRegistration = registration;\r\n\r\n });\r\n SWUpdateService.checkUpdates($rootScope.SWRegistration);\r\n }\r\n //END - SERVICE WORKERS\r\n \r\n $anchorScroll.yOffset = 100;\r\n \r\n if(valid.indexOf($location.$$path) < 0 && (!current || !current.$$route || !next.$$route || current.$$route.controller != next.$$route.controller)){\r\n //Check if temp report of any kind exists\r\n var editingPage = SettingsMain.getEditingPage();\r\n SettingsMain.setEditingPage(null);\r\n\r\n if (editingPage == 'report') {\r\n // check if a temp report exists in local storage\r\n if (CabinReportLocalEditFactory.getCabinReportLocalEditFromTemp() != null) {\r\n $location.path(\"report/temp\");\r\n }\r\n } \r\n else if (editingPage == 'assessment') {\r\n // check if a temp assessment exists in local storage\r\n if (CrewAssessmentFactory.getTempAssessment() != null) {\r\n $location.path(\"assessment/temp\");\r\n }\r\n }\r\n\r\n //Method: Clear specific cache on route change\r\n if (typeof(current) !== 'undefined') {\r\n $templateCache.remove(current.templateUrl);\r\n }\r\n\r\n \r\n }\r\n \r\n });\r\n \r\n \r\n $rootScope.idbSupported = (\"indexedDB\" in window);\r\n \r\n $rootScope.isOffline = !window.navigator.onLine;\r\n \r\n window.addEventListener('offline', function (e) { $timeout($rootScope.isOffline = !window.navigator.onLine); });\r\n window.addEventListener('online', function (e) { $timeout($rootScope.isOffline = !window.navigator.onLine); });\r\n \r\n \r\n $(\"body\").on(\"click\",\".memo-body a\", function(){\r\n var link = $(this).attr(\"href\");\r\n if (link && link.indexOf(\"surveymonkey\")>0){\r\n LogService.debug(link);\r\n }\r\n \r\n })\r\n \r\n //maintain the user token, outside the localStorage, needed for submitting js errors\r\n var user = UserFactory.getUser();\r\n if (user && user.token) \r\n UserTokenFactory.setToken(user.token);\r\n else \r\n UserTokenFactory.setToken('');\r\n}\r\n \r\n})();","(function () {\r\n// Warning!!! This an auto generated file. Any Changes will be lost. If u want to add or edit go to config.json \r\n\r\na3_cabin_reports.constant(\"liveVersion\", true);\r\n\r\na3_cabin_reports.constant(\"defaultCalendarDate\", null);\r\n\r\na3_cabin_reports.constant(\"defaultBucketDate\", null);\r\n\r\na3_cabin_reports.constant(\"apiUrl\", \"https://cabinreport.aegeanair.com/api/v1.34\");\r\n\r\na3_cabin_reports.constant(\"azureADAuth\", {\n\t\"clientId\": \"064e4b4c-57b9-434f-aee8-28156709fab8\",\n\t\"tenantId\": \"00ab5264-f7ed-4d89-9011-19bf33ed8169\",\n\t\"authority\": \"https://login.microsoftonline.com/aegeancloud.onmicrosoft.com\"\n});\r\n\r\na3_cabin_reports.constant(\"customerIncidentQuestionIds\", [\n\t220,\n\t222\n]);\r\n\r\na3_cabin_reports.constant(\"enableFaceMasks\", false);\r\n\r\na3_cabin_reports.constant(\"ssrCodes\", [\n\t{\n\t\t\"code\": \"AOXY\",\n\t\t\"description\": \"Airline Supplied Oxygen\"\n\t},\n\t{\n\t\t\"code\": \"AVIH\",\n\t\t\"description\": \"Animal in Hold\"\n\t},\n\t{\n\t\t\"code\": \"AVML\",\n\t\t\"description\": \"Vegetarian Hindu meal\"\n\t},\n\t{\n\t\t\"code\": \"BBNL\",\n\t\t\"description\": \"Baby meal request\"\n\t},\n\t{\n\t\t\"code\": \"BIKE\",\n\t\t\"description\": \"Request for carriage of bicycle\"\n\t},\n\t{\n\t\t\"code\": \"BLML\",\n\t\t\"description\": \"Bland meal request\"\n\t},\n\t{\n\t\t\"code\": \"BLND\",\n\t\t\"description\": \"Blind passenger information\"\n\t},\n\t{\n\t\t\"code\": \"CBBG\",\n\t\t\"description\": \"Bulky cabin baggage request\"\n\t},\n\t{\n\t\t\"code\": \"CHLD\",\n\t\t\"description\": \"Child information\"\n\t},\n\t{\n\t\t\"code\": \"CHML\",\n\t\t\"description\": \"Child Meal Request\"\n\t},\n\t{\n\t\t\"code\": \"DBML\",\n\t\t\"description\": \"Diabetic meal request\"\n\t},\n\t{\n\t\t\"code\": \"DEAF\",\n\t\t\"description\": \"Deaf passenger information\"\n\t},\n\t{\n\t\t\"code\": \"DEPA\",\n\t\t\"description\": \"Accompanied Deportee Information\"\n\t},\n\t{\n\t\t\"code\": \"DEPU\",\n\t\t\"description\": \"Deportee unaccompanied\"\n\t},\n\t{\n\t\t\"code\": \"DHCS\",\n\t\t\"description\": \"Deadhead crew seating\"\n\t},\n\t{\n\t\t\"code\": \"DPNA\",\n\t\t\"description\": \"Disabled passenger needing assistance\"\n\t},\n\t{\n\t\t\"code\": \"EMIG\",\n\t\t\"description\": \"Emigrant\"\n\t},\n\t{\n\t\t\"code\": \"ESAN\",\n\t\t\"description\": \"Passenger with emotional support/psychiatric\"\n\t},\n\t{\n\t\t\"code\": \"ESCD\",\n\t\t\"description\": \"Passenger escorting deportee\"\n\t},\n\t{\n\t\t\"code\": \"EXST\",\n\t\t\"description\": \"Request for extra seat\"\n\t},\n\t{\n\t\t\"code\": \"FAMS\",\n\t\t\"description\": \"Family seating\"\n\t},\n\t{\n\t\t\"code\": \"FPML\",\n\t\t\"description\": \"Fruit platter meal request\"\n\t},\n\t{\n\t\t\"code\": \"FRED\",\n\t\t\"description\": \"Meal and assist request\"\n\t},\n\t{\n\t\t\"code\": \"GFML\",\n\t\t\"description\": \"Gluten intolerant meal request\"\n\t},\n\t{\n\t\t\"code\": \"GPST\",\n\t\t\"description\": \"Group seating request\"\n\t},\n\t{\n\t\t\"code\": \"HAJJ\",\n\t\t\"description\": \"HAJJ Passengers\"\n\t},\n\t{\n\t\t\"code\": \"HNML\",\n\t\t\"description\": \"Hindu meal request\"\n\t},\n\t{\n\t\t\"code\": \"INAD\",\n\t\t\"description\": \"Inadmissable\"\n\t},\n\t{\n\t\t\"code\": \"INFT\",\n\t\t\"description\": \"Infant information\"\n\t},\n\t{\n\t\t\"code\": \"KSML\",\n\t\t\"description\": \"Kosher meal request\"\n\t},\n\t{\n\t\t\"code\": \"LCML\",\n\t\t\"description\": \"Low calorie meal request\"\n\t},\n\t{\n\t\t\"code\": \"LFML\",\n\t\t\"description\": \"Low fat meal request\"\n\t},\n\t{\n\t\t\"code\": \"LSML\",\n\t\t\"description\": \"Low salt meal request\"\n\t},\n\t{\n\t\t\"code\": \"MAAS\",\n\t\t\"description\": \"Meet and assist request\"\n\t},\n\t{\n\t\t\"code\": \"MEDA\",\n\t\t\"description\": \"Medical assistance information\"\n\t},\n\t{\n\t\t\"code\": \"MEQT\",\n\t\t\"description\": \"Medical equipment\"\n\t},\n\t{\n\t\t\"code\": \"MOML\",\n\t\t\"description\": \"Halaal meal request\"\n\t},\n\t{\n\t\t\"code\": \"NFML\",\n\t\t\"description\": \"No fish meal request\"\n\t},\n\t{\n\t\t\"code\": \"NLML\",\n\t\t\"description\": \"Low lactose meal request\"\n\t},\n\t{\n\t\t\"code\": \"NOML\",\n\t\t\"description\": \"Meal on board not required\"\n\t},\n\t{\n\t\t\"code\": \"PETC\",\n\t\t\"description\": \"Pet in cabin request\"\n\t},\n\t{\n\t\t\"code\": \"POXY\",\n\t\t\"description\": \"Passenger own oxygen\"\n\t},\n\t{\n\t\t\"code\": \"RVML\",\n\t\t\"description\": \"Vegetarian raw meal request\"\n\t},\n\t{\n\t\t\"code\": \"SEML\",\n\t\t\"description\": \"Seafood meal request\"\n\t},\n\t{\n\t\t\"code\": \"SFML\",\n\t\t\"description\": \"Seafood meal request\"\n\t},\n\t{\n\t\t\"code\": \"SPML\",\n\t\t\"description\": \"Special meal request\"\n\t},\n\t{\n\t\t\"code\": \"SVAN\",\n\t\t\"description\": \"Passenger with service animal in cabin\"\n\t},\n\t{\n\t\t\"code\": \"UMNR\",\n\t\t\"description\": \"Unaccompanied minor information\"\n\t},\n\t{\n\t\t\"code\": \"VGML\",\n\t\t\"description\": \"Vegetarian vegan meal request\"\n\t},\n\t{\n\t\t\"code\": \"VJML\",\n\t\t\"description\": \"Vegetarian Jain meal request\"\n\t},\n\t{\n\t\t\"code\": \"VLML\",\n\t\t\"description\": \"Vegetarian Lacto-Ovo meal request\"\n\t},\n\t{\n\t\t\"code\": \"VOML\",\n\t\t\"description\": \"Vegetarian Oriental meal request\"\n\t},\n\t{\n\t\t\"code\": \"WCBD\",\n\t\t\"description\": \"Wheelchair Dry-cell battery request\"\n\t},\n\t{\n\t\t\"code\": \"WCBW\",\n\t\t\"description\": \"Wheelchair Wet-cell battery request\"\n\t},\n\t{\n\t\t\"code\": \"WCHC\",\n\t\t\"description\": \"Wheelchair To seat request\"\n\t},\n\t{\n\t\t\"code\": \"WCHR\",\n\t\t\"description\": \"Wheelchair To aircraft door request\"\n\t},\n\t{\n\t\t\"code\": \"WCHS\",\n\t\t\"description\": \"Wheelchair Up/down stairs request\"\n\t},\n\t{\n\t\t\"code\": \"WCLB\",\n\t\t\"description\": \"Wheelchair - Lithium ion Battery\"\n\t},\n\t{\n\t\t\"code\": \"WCMP\",\n\t\t\"description\": \"Wheelchair Manual powered request\"\n\t},\n\t{\n\t\t\"code\": \"WCOB\",\n\t\t\"description\": \"Wheelchair On board request\"\n\t},\n\t{\n\t\t\"code\": \"WEAP\",\n\t\t\"description\": \"WEAP Firearms or ammunition booked & carried as checked\"\n\t},\n\t{\n\t\t\"code\": \"XBGS\",\n\t\t\"description\": \"DCS Excess Baggage Request\"\n\t},\n\t{\n\t\t\"code\": \"FAML\",\n\t\t\"description\": \"BC HB choice A\"\n\t},\n\t{\n\t\t\"code\": \"FBML\",\n\t\t\"description\": \"BC HB choice B\"\n\t},\n\t{\n\t\t\"code\": \"BFML\",\n\t\t\"description\": \"BC HML beef choice\"\n\t},\n\t{\n\t\t\"code\": \"CKML\",\n\t\t\"description\": \"BC HML chicken choice\"\n\t},\n\t{\n\t\t\"code\": \"FSML\",\n\t\t\"description\": \"BC HML fish choice\"\n\t},\n\t{\n\t\t\"code\": \"COML\",\n\t\t\"description\": \"Cold cut platter\"\n\t},\n\t{\n\t\t\"code\": \"DEML\",\n\t\t\"description\": \"Dessert choice\"\n\t}\n]);\r\n\r\na3_cabin_reports.constant(\"bookmarkThreshold\", 15);\r\n\r\na3_cabin_reports.constant(\"turnArroundTimesAcTypes\", [\n\t\"319\",\n\t\"320\",\n\t\"321\",\n\t\"32Q\",\n\t\"32N\",\n\t\"32X\"\n]);\r\n\r\na3_cabin_reports.constant(\"waterUpliftSupportingAcTypes\", [\n\t\"319\",\n\t\"320\",\n\t\"321\",\n\t\"32Q\",\n\t\"32N\",\n\t\"32X\"\n]);\r\n\r\na3_cabin_reports.constant(\"enableWaterUpliftReporting\", false);\r\n\r\na3_cabin_reports.constant(\"operationalPhases\", [\n\t{\n\t\t\"key\": \"3287\",\n\t\t\"value\": \"On Stand\"\n\t},\n\t{\n\t\t\"key\": \"3288\",\n\t\t\"value\": \"Towing\"\n\t},\n\t{\n\t\t\"key\": \"9242\",\n\t\t\"value\": \"Towing - Stand to Stand\"\n\t},\n\t{\n\t\t\"key\": \"9243\",\n\t\t\"value\": \"Towing - to/from maint\"\n\t},\n\t{\n\t\t\"key\": \"3289\",\n\t\t\"value\": \"Parked\"\n\t},\n\t{\n\t\t\"key\": \"3290\",\n\t\t\"value\": \"Pushback\"\n\t},\n\t{\n\t\t\"key\": \"3291\",\n\t\t\"value\": \"Taxi-out\"\n\t},\n\t{\n\t\t\"key\": \"3292\",\n\t\t\"value\": \"Take-off\"\n\t},\n\t{\n\t\t\"key\": \"3293\",\n\t\t\"value\": \"Initial Climb\"\n\t},\n\t{\n\t\t\"key\": \"3294\",\n\t\t\"value\": \"Climb\"\n\t},\n\t{\n\t\t\"key\": \"3295\",\n\t\t\"value\": \"Cruise\"\n\t},\n\t{\n\t\t\"key\": \"3296\",\n\t\t\"value\": \"Descent\"\n\t},\n\t{\n\t\t\"key\": \"3297\",\n\t\t\"value\": \"Holding\"\n\t},\n\t{\n\t\t\"key\": \"3298\",\n\t\t\"value\": \"Approach\"\n\t},\n\t{\n\t\t\"key\": \"3299\",\n\t\t\"value\": \"Landing\"\n\t},\n\t{\n\t\t\"key\": \"3300\",\n\t\t\"value\": \"Taxi-in\"\n\t},\n\t{\n\t\t\"key\": \"3301\",\n\t\t\"value\": \"Maintenance\"\n\t},\n\t{\n\t\t\"key\": \"3302\",\n\t\t\"value\": \"All\"\n\t},\n\t{\n\t\t\"key\": \"3303\",\n\t\t\"value\": \"In Aircraft\"\n\t},\n\t{\n\t\t\"key\": \"3304\",\n\t\t\"value\": \"In Position at Aircraft\"\n\t},\n\t{\n\t\t\"key\": \"3305\",\n\t\t\"value\": \"In Transit To / From Stand\"\n\t},\n\t{\n\t\t\"key\": \"3306\",\n\t\t\"value\": \"Moving on Stand\"\n\t},\n\t{\n\t\t\"key\": \"3307\",\n\t\t\"value\": \"Positioning to Aircraft\"\n\t},\n\t{\n\t\t\"key\": \"3308\",\n\t\t\"value\": \"Removing from Aircraft\"\n\t},\n\t{\n\t\t\"key\": \"3309\",\n\t\t\"value\": \"Other\"\n\t},\n\t{\n\t\t\"key\": \"3310\",\n\t\t\"value\": \"Hover\"\n\t},\n\t{\n\t\t\"key\": \"3311\",\n\t\t\"value\": \"In Flight\"\n\t},\n\t{\n\t\t\"key\": \"3312\",\n\t\t\"value\": \"Multiple\"\n\t},\n\t{\n\t\t\"key\": \"3313\",\n\t\t\"value\": \"Parked On / By Stand\"\n\t},\n\t{\n\t\t\"key\": \"9241\",\n\t\t\"value\": \"Arrival\"\n\t},\n\t{\n\t\t\"key\": \"9244\",\n\t\t\"value\": \"Arrival - Marshaling\"\n\t},\n\t{\n\t\t\"key\": \"9245\",\n\t\t\"value\": \"Arrival - Guidance\"\n\t},\n\t{\n\t\t\"key\": \"9246\",\n\t\t\"value\": \"Servicing\"\n\t},\n\t{\n\t\t\"key\": \"9247\",\n\t\t\"value\": \"Servicing - De-icing\"\n\t},\n\t{\n\t\t\"key\": \"9248\",\n\t\t\"value\": \"Servicing - Fueling\"\n\t},\n\t{\n\t\t\"key\": \"9249\",\n\t\t\"value\": \"Servicing - Catering\"\n\t},\n\t{\n\t\t\"key\": \"9250\",\n\t\t\"value\": \"Servicing - Lavatory\"\n\t},\n\t{\n\t\t\"key\": \"9251\",\n\t\t\"value\": \"Servicing - Water\"\n\t},\n\t{\n\t\t\"key\": \"9252\",\n\t\t\"value\": \"Servicing - Cleaning\"\n\t},\n\t{\n\t\t\"key\": \"9253\",\n\t\t\"value\": \"Servicing - Line Maint\"\n\t},\n\t{\n\t\t\"key\": \"9254\",\n\t\t\"value\": \"Servicing - Coning\"\n\t},\n\t{\n\t\t\"key\": \"9255\",\n\t\t\"value\": \"Servicing - GPU\"\n\t},\n\t{\n\t\t\"key\": \"9256\",\n\t\t\"value\": \"Servicing - PCA\"\n\t},\n\t{\n\t\t\"key\": \"9257\",\n\t\t\"value\": \"Servicing - Bridging\"\n\t},\n\t{\n\t\t\"key\": \"9258\",\n\t\t\"value\": \"Servicing - Chocking\"\n\t},\n\t{\n\t\t\"key\": \"9259\",\n\t\t\"value\": \"Loading\"\n\t},\n\t{\n\t\t\"key\": \"9260\",\n\t\t\"value\": \"Loading - Passenger\"\n\t},\n\t{\n\t\t\"key\": \"9261\",\n\t\t\"value\": \"Loading - Baggage\"\n\t},\n\t{\n\t\t\"key\": \"9262\",\n\t\t\"value\": \"Loading - Cargo\"\n\t},\n\t{\n\t\t\"key\": \"9263\",\n\t\t\"value\": \"Unloading\"\n\t},\n\t{\n\t\t\"key\": \"9264\",\n\t\t\"value\": \"Unloading - Passenger\"\n\t},\n\t{\n\t\t\"key\": \"9265\",\n\t\t\"value\": \"Unloading - Baggage\"\n\t},\n\t{\n\t\t\"key\": \"9266\",\n\t\t\"value\": \"Unloading - Cargo\"\n\t}\n]);\r\n\r\n})();","(function () {\r\n// Warning!!! This an auto generated file. Any Changes will be lost. If u want to add or edit go to config.json \r\n\r\na3_cabin_reports.constant(\"version\", \"appVersion_20250205104221\");\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\n //Default Configuration For Charts\r\n\r\n a3_cabin_reports.constant('barOptions', barOptions);\r\n a3_cabin_reports.constant('pieDoughnutOptions', pieDoughnutOptions);\r\n\r\n var barOptions = {\r\n ///Boolean - Whether grid lines are shown across the chart\r\n scaleShowGridLines: true,\r\n //String - Colour of the grid lines\r\n scaleGridLineColor: \"rgba(0,0,0,.05)\",\r\n //Number - Width of the grid lines\r\n scaleGridLineWidth: 1,\r\n //Boolean - Whether to show horizontal lines (except X axis)\r\n scaleShowHorizontalLines: true,\r\n //Boolean - Whether to show vertical lines (except Y axis)\r\n scaleShowVerticalLines: true,\r\n //Boolean - Whether the line is curved between points\r\n bezierCurve: true,\r\n //Number - Tension of the bezier curve between points\r\n bezierCurveTension: 0.4,\r\n //Boolean - Whether to show a dot for each point\r\n pointDot: true,\r\n //Number - Radius of each point dot in pixels\r\n pointDotRadius: 4,\r\n //Number - Pixel width of point dot stroke\r\n pointDotStrokeWidth: 1,\r\n //Number - amount extra to add to the radius to cater for hit detection outside the drawn point\r\n pointHitDetectionRadius: 20,\r\n //Boolean - Whether to show a stroke for datasets\r\n datasetStroke: true,\r\n //Number - Pixel width of dataset stroke\r\n datasetStrokeWidth: 2,\r\n //Boolean - Whether to fill the dataset with a colour\r\n datasetFill: true,\r\n //String - A legend template\r\n legendTemplate: \"
    -legend\\\"><% for (var i=0; i
  • \\\"><%if(datasets[i].label){%><%=datasets[i].label%><%}%>
  • <%}%>
\"\r\n };\r\n \r\n var pieDoughnutOptions = {\r\n //Boolean - Whether we should show a stroke on each segment\r\n segmentShowStroke: true,\r\n //String - The colour of each segment stroke\r\n segmentStrokeColor: \"#fff\",\r\n //Number - The width of each segment stroke\r\n segmentStrokeWidth: 2,\r\n //Number - The percentage of the chart that we cut out of the middle\r\n percentageInnerCutout: 50, // This is 0 for Pie charts\r\n //Number - Amount of animation steps\r\n animationSteps: 100,\r\n //String - Animation easing effect\r\n animationEasing: \"easeOutBounce\",\r\n //Boolean - Whether we animate the rotation of the Doughnut\r\n animateRotate: true,\r\n //Boolean - Whether we animate scaling the Doughnut from the centre\r\n animateScale: false,\r\n //String - A legend template\r\n legendTemplate: \"
    -legend\\\"><% for (var i=0; i
  • \\\"><%if(segments[i].label){%><%=segments[i].label%><%}%>
  • <%}%>
\",\r\n onAnimationComplete: function() {\r\n this.showTooltip(this.segments, true);\r\n },\r\n tooltipEvents: [],\r\n showTooltips: true\r\n };\r\n \r\n})();\r\n\r\n \r\n\r\n","(function () {\r\n 'use strict';\r\n\r\n angular.module('MyDirectives', [])\r\n /**\r\n * HTML5 SignaturePad Directive\r\n * This directive is intended to place a canvas within a form\r\n * which can then be drawn upon. Once it is drawn updon, it will be\r\n * considered 'valid'\r\n *\r\n * Thanks to Thomas J Bradley for the Signature Pad plugin for jQuery\r\n * http://thomasjbradley.ca/lab/signature-pad/\r\n *\r\n */\r\n .directive('sigpad', function ($timeout) {\r\n return {\r\n templateUrl: 'views/sigPad.html', // Use a template in an external file\r\n restrict: 'E', // Must use element to invoke directive\r\n scope: true, // Create a new scope for the directive\r\n require: 'ngModel', // Require the ngModel controller for the linking function\r\n link: function (scope, element, attr, ctrl) {\r\n\r\n // Attach the Signature Pad plugin to the template and keep a reference to the signature pad as 'sigPadAPI'\r\n var sigPadAPI = $(element).signaturePad({\r\n drawOnly: true,\r\n lineColour: '#FFF',\r\n penWidth: 6\r\n });\r\n\r\n // Clear the canvas when the 'clear' button is clicked\r\n $(attr.clearbtn).on('click', function (e) {\r\n sigPadAPI.clearCanvas();\r\n });\r\n\r\n $(element).find('.pad').on('touchend', function (obj) {\r\n scope.updateModel();\r\n });\r\n\r\n // when the mouse is lifted from the canvas, set the signature pad data as the model value\r\n scope.updateModel = function () {\r\n $timeout(function () {\r\n var sig = sigPadAPI.getSignature();\r\n if (sig != null && sig.length == 0) {\r\n var sig = null;\r\n }\r\n ctrl.$setViewValue(sig);\r\n });\r\n };\r\n\r\n // Render the signature data when the model has data. Otherwise clear the canvas.\r\n ctrl.$render = function () {\r\n if (ctrl.$viewValue) {\r\n sigPadAPI.regenerate(ctrl.$viewValue);\r\n } else {\r\n // This occurs when signatureData is set to null in the main controller\r\n sigPadAPI.clearCanvas();\r\n }\r\n };\r\n\r\n // Validate signature pad.\r\n // See http://docs.angularjs.org/guide/forms for more detail on how this works.\r\n ctrl.$parsers.unshift(function (viewValue) {\r\n if (sigPadAPI.validateForm()) {\r\n ctrl.$setValidity('sigpad', true);\r\n return viewValue;\r\n } else {\r\n ctrl.$setValidity('sigpad', false);\r\n //undefined to viewValue cause of bug\r\n return viewValue;\r\n }\r\n });\r\n\r\n }\r\n };\r\n })\r\n /**\r\n * Regenerate Signature Pad data as Base64 encoded PNG data.\r\n * This uses the getSignatureImage() function of the Signature Pad API.\r\n * It only works in modern browsers, and is flaky in IE.\r\n */\r\n .directive('regensigpad', function () {\r\n return {\r\n template: '',\r\n restrict: 'E',\r\n scope: {\r\n sigdata: '@'\r\n },\r\n link: function (scope, element, attr, ctrl) {\r\n // When the sigdata attribute changes...\r\n attr.$observe('sigdata', function (val) {\r\n // ... create a blank canvas template and attach the signature pad plugin\r\n var sigPadAPI = $('
').signaturePad({\r\n displayOnly: true\r\n });\r\n // regenerate the signature onto the canvas\r\n if (val) {\r\n sigPadAPI.regenerate(val);\r\n } else {\r\n // This occurs when signatureData is set to null in the main controller\r\n sigPadAPI.clearCanvas();\r\n }\r\n // convert the canvas to a PNG (Newer versions of Chrome, FF, and Safari only.)\r\n scope.pic = sigPadAPI.getSignatureImage();\r\n });\r\n }\r\n };\r\n })\r\n\r\n /* Used to capture images from the device's camera\r\n * and resize them using given dimensions and quality\r\n * \r\n */\r\n .directive('image', function ($q) {\r\n 'use strict'\r\n\r\n var URL = window.URL || window.webkitURL;\r\n\r\n return {\r\n restrict: 'A',\r\n scope: {\r\n /*image: '=',*/\r\n maxwidth: '@?',\r\n maxheight: '@?',\r\n quality: '@?',\r\n imagetype: '@?',\r\n onfilechange: '&'\r\n },\r\n link: function postLink(scope, element, attrs, ctrl) {\r\n var onFileChangeCallback = scope.onfilechange;\r\n var onFileFailureCallback = scope.onfileerror;\r\n var filename = \"\";\r\n var options;\r\n\r\n var getOptions = function () {\r\n var options = {\r\n maxWidth: parseFloat(scope.maxwidth) || 1024,\r\n maxHeight: parseFloat(scope.maxheight) || 768,\r\n quality: parseFloat(scope.quality) || 0.8,\r\n imageType: scope.imagetype || 'image/jpeg',\r\n canvas: true\r\n };\r\n return options;\r\n }\r\n\r\n var whenError = function (errorMessage) {\r\n scope.$apply(function () {\r\n if (typeof (onFileFailureCallback) == 'function') {\r\n //to pass data in the message, we need to have an object with attrs named as in\r\n //the html part, eg onfilechange=\"imageChanged(data)\"\r\n onFileFailureCallback({\r\n err: errorMessage\r\n });\r\n }\r\n });\r\n }\r\n\r\n var whenReady = function (img) {\r\n if (!(img.src || img instanceof HTMLCanvasElement)) {\r\n whenError('Loading image file failed');\r\n } else {\r\n var data = img.src || img.toDataURL(options.imageType, options.quality);\r\n var imageResult = {\r\n dataURL: data,\r\n fileName: filename,\r\n fileType: options.imageType\r\n };\r\n scope.$apply(function () {\r\n if (typeof (onFileChangeCallback) == 'function') {\r\n //to pass data in the message, we need to have an object with attrs named as in\r\n //the html part, eg onfilechange=\"imageChanged(data)\"\r\n onFileChangeCallback({\r\n data: imageResult\r\n });\r\n }\r\n });\r\n }\r\n }\r\n\r\n element.bind('change', function (evt) {\r\n evt.preventDefault();\r\n //e = e.originalEvent;\r\n var target = evt.dataTransfer || evt.target;\r\n var files = target && target.files;\r\n if (files) {\r\n var file;\r\n options = getOptions(); //read latest settings\r\n for (var i = 0; i < files.length; i++) {\r\n file = files[i];\r\n filename = file.name;\r\n //start by get metadata, to autoset the orientation of the image\r\n loadImage.parseMetaData(file,\r\n //when metadata are ready, use them and then load image\r\n function (data) {\r\n if (data.exif) {\r\n options.orientation = data.exif.get('Orientation');\r\n }\r\n if (!loadImage(file, whenReady, options)) {\r\n whenError('Your browser does not support capturing images.');\r\n }\r\n }\r\n );\r\n }\r\n }\r\n });\r\n }\r\n };\r\n })\r\n\r\n .directive('integer', function () {\r\n return {\r\n require: 'ngModel',\r\n link: function (scope, elm, attrs, ctrl) {\r\n ctrl.$parsers.unshift(function (viewValue) {\r\n var INTEGER_REGEXP = /^\\-?\\d+$/;\r\n if (INTEGER_REGEXP.test(viewValue)) {\r\n // it is valid\r\n ctrl.$setValidity('integer', true);\r\n return viewValue;\r\n } else {\r\n // it is invalid, return undefined (no model update)\r\n ctrl.$setValidity('integer', false);\r\n return undefined;\r\n }\r\n });\r\n }\r\n };\r\n })\r\n\r\n .directive('smartFloat', function () {\r\n return {\r\n require: 'ngModel',\r\n link: function (scope, elm, attrs, ctrl) {\r\n ctrl.$parsers.unshift(function (viewValue) {\r\n var FLOAT_REGEXP = /^\\-?\\d+((\\.|\\,)\\d+)?$/;\r\n if (FLOAT_REGEXP.test(viewValue)) {\r\n ctrl.$setValidity('float', true);\r\n return parseFloat(viewValue.replace(',', '.'));\r\n } else {\r\n ctrl.$setValidity('float', false);\r\n return undefined;\r\n }\r\n });\r\n }\r\n };\r\n })\r\n\r\n .directive('validNumber', function () {\r\n return function (scope, element, attrs) {\r\n\r\n // var keyCode = [8,9,37,39, 46,48,49,50,51,52,53,54,55,56,57 ,96,97,98,99,100,101,102,103,104,105,110];\r\n var keyCode = [8, 46, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 110, 190];\r\n element.bind(\"keydown\", function (event) {\r\n if ($.inArray(event.which, keyCode) == -1) {\r\n scope.$apply(function () {\r\n scope.$eval(attrs.onlyNum);\r\n event.preventDefault();\r\n });\r\n event.preventDefault();\r\n }\r\n\r\n });\r\n };\r\n })\r\n\r\n .directive('chart', function () {\r\n var baseWidth = 600;\r\n var baseHeight = 400;\r\n\r\n return {\r\n restrict: 'E',\r\n template: '',\r\n scope: {\r\n chartObject: \"=value\"\r\n },\r\n link: function (scope, element, attrs) {\r\n var canvas = element.find('canvas')[0];\r\n var context = canvas.getContext('2d');\r\n var chart;\r\n\r\n var options = {\r\n type: attrs.type || \"Line\",\r\n width: attrs.width || baseWidth,\r\n height: attrs.height || baseHeight\r\n };\r\n canvas.width = options.width;\r\n canvas.height = options.height;\r\n chart = new Chart(context);\r\n\r\n if (scope.chartObject) {\r\n\r\n\r\n scope.$watch(function () {\r\n return element.attr('type');\r\n }, function (value) {\r\n if (!value) return;\r\n options.type = value;\r\n var chartType = options.type;\r\n chart[chartType](scope.chartObject.data, scope.chartObject.options);\r\n });\r\n\r\n //Update when charts data changes\r\n scope.$watch(function () {\r\n return scope.chartObject;\r\n }, function (value) {\r\n if (!value) return;\r\n var chartType = options.type;\r\n chart[chartType](scope.chartObject.data, scope.chartObject.options);\r\n if (scope.chartInstance) scope.chartInstance.destroy();\r\n scope.chartInstance = chart[chartType](scope.chartObject.data, scope.chartObject.options);\r\n }, true);\r\n\r\n }\r\n }\r\n }\r\n })\r\n\r\n .directive('canvasGauge', function () {\r\n return {\r\n restrict: 'E',\r\n replace: true,\r\n template: '',\r\n scope: {\r\n val: '=value'\r\n },\r\n link: function ($scope, element, attrs) {\r\n\r\n var width = parseInt(attrs.width || '100');\r\n $scope.height = width * 0.55;\r\n element.attr('height', $scope.height + 'px');\r\n\r\n var placeholder = attrs.placeholder || '(@)';\r\n var mask = attrs.mask || placeholder;\r\n var canvas = element[0];\r\n\r\n var animID = 0;\r\n var curValue = 0;\r\n var endValue = 0;\r\n var oldValue = 0;\r\n var direction = 0;\r\n\r\n var render = function (val) {\r\n\r\n var value = val || 0;\r\n\r\n if (canvas.getContext) {\r\n var ctx = canvas.getContext('2d');\r\n ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n\r\n var calcPercent = function (total, perc) {\r\n return (total * perc) / 100;\r\n }\r\n\r\n var per = ((value - $scope.min) * 100) / ($scope.max - $scope.min); // Value converted to percentage using min and max\r\n var pad = calcPercent(canvas.width, 15); // Inner padding around the container\r\n var x = canvas.width / 2; // x coordinate\r\n var y = (canvas.width / 2.3); // y coordinate\r\n var startAngle = 0; // Starting point on circle\r\n var radius = x - pad; // Circle's radius\r\n var lineWidth = (canvas.width / 8); // Thickness of the drawing tip\r\n var fontSize = (canvas.width * 0.1); // Default size of the text font (10% of canvas width)\r\n\r\n ctx.imageSmoothingEnabled = true;\r\n ctx.shadowOffsetX = 0;\r\n ctx.shadowOffsetY = 0;\r\n ctx.shadowBlur = 0;\r\n\r\n ctx.beginPath();\r\n ctx.arc(x, y, radius, Math.PI, Math.PI * 2, false);\r\n ctx.lineWidth = lineWidth;\r\n ctx.strokeStyle = $scope.underColor;\r\n ctx.stroke();\r\n ctx.closePath();\r\n\r\n var endAngle = ((Math.PI * per) / 100) + Math.PI;\r\n ctx.beginPath();\r\n ctx.arc(x, y, radius, Math.PI, endAngle, false);\r\n ctx.lineWidth = lineWidth;\r\n ctx.strokeStyle = $scope.overColor;\r\n ctx.stroke();\r\n ctx.closePath();\r\n\r\n ctx.font = 'bold ' + fontSize + 'pt Calibri';\r\n ctx.textAlign = 'center';\r\n ctx.fillStyle = $scope.textColor;\r\n ctx.shadowColor = $scope.shadeColors($scope.smallTextColor, -30);\r\n ctx.shadowOffsetX = 1;\r\n ctx.shadowOffsetY = 1;\r\n ctx.shadowBlur = 0;\r\n ctx.fillText(mask.replace(placeholder, parseFloat(value.toFixed(2)).toString()), x, y);\r\n\r\n if (canvas.width > 119) {\r\n y = (canvas.width / 2.2) + calcPercent(canvas.height, 10) + (canvas.width / 100) - 1;\r\n x = pad;\r\n ctx.font = 'normal ' + (fontSize / 2) + 'pt Calibri';\r\n ctx.shadowOffsetX = 0;\r\n ctx.shadowOffsetY = 0;\r\n ctx.fillStyle = $scope.smallTextColor;\r\n ctx.fillText($scope.min, x, y);\r\n\r\n y = (canvas.width / 2.2) + calcPercent(canvas.height, 10) + (canvas.width / 100) - 1;\r\n x = canvas.width - (pad);\r\n ctx.font = 'normal ' + (fontSize / 2) + 'pt Calibri';\r\n ctx.fillStyle = $scope.smallTextColor;\r\n ctx.fillText($scope.max, x, y);\r\n }\r\n }\r\n }\r\n\r\n var animate = function () {\r\n\r\n var flag = direction == 1 ? (curValue <= endValue) : (curValue >= endValue);\r\n if (flag == true) {\r\n render(curValue);\r\n\r\n curValue += direction;\r\n animID = requestAnimationFrame(animate);\r\n } else {\r\n oldValue = endValue;\r\n render(endValue);\r\n cancelAnimationFrame(animID);\r\n }\r\n }\r\n\r\n $scope.shadeColors = function (color, percent) {\r\n\r\n var f = parseInt(color.slice(1), 16),\r\n t = percent < 0 ? 0 : 255;\r\n var p = percent < 0 ? percent * -1 : percent;\r\n var R = f >> 16;\r\n var G = f >> 8 & 0x00FF;\r\n var B = f & 0x0000FF;\r\n return \"#\" + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);\r\n }\r\n\r\n $scope.$watch('val', function (newval, oldval) {\r\n\r\n $scope.min = attrs.min || 0;\r\n $scope.max = attrs.max || 100;\r\n $scope.underColor = attrs.underColor || '#EFEFEF';\r\n $scope.overColor = attrs.overColor || '#000';\r\n $scope.textColor = attrs.textColor || $scope.overColor\r\n $scope.smallTextColor = attrs.smallTextColor || getComputedStyle(element[0]).getPropertyValue(\"color\");\r\n\r\n curValue = parseFloat(oldValue);\r\n endValue = parseFloat(newval); //alert(curValue + ' -- ' + endValue);\r\n direction = endValue < curValue ? -1 : 1;\r\n animate();\r\n\r\n });\r\n\r\n }\r\n }\r\n })\r\n\r\n .directive('bsHasError', [function () {\r\n return {\r\n restrict: \"A\",\r\n link: function (scope, element, attrs, ctrl) {\r\n var input = element.find('input[ng-model]');\r\n if (input) {\r\n scope.$watch(function () {\r\n return input.hasClass('ng-invalid') && input.hasClass('ng-dirty');\r\n }, function (isInvalid) {\r\n element.toggleClass('has-error', isInvalid);\r\n });\r\n }\r\n }\r\n };\r\n}]);\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('AirportContactFactory',AirportContactFactory);\r\n \r\n /**\r\n * @memberof PilotReports\r\n * @ngdoc factory\r\n * @name AirportContactFactory\r\n * @description \r\n * Add, Update, Delete and Get Airport Contacts.\r\n * @ngInject\r\n */\r\nfunction AirportContactFactory(GenericService){\r\n \r\n /**\r\n * Initialize the AirportContact\r\n * @memberof AirportContactFactory\r\n */\r\n\t\tfunction Airport() {\r\n this.Iata=null;\r\n this.Contacts=null;\r\n }\r\n \r\n \r\n\t\tvar objType = 'airportContacts';\r\n\t\tvar objCallback = Airport; \r\n\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tgetAirportContactsFromStorage : getAirportContactsFromStorage,\r\n\t\t\tsetAirportContactsToStorage : setAirportContactsToStorage,\r\n clearAirportContactsFromStorage : clearAirportContactsFromStorage,\r\n getAirportContacts: getAirportContacts,\r\n upsertAirportContacts: upsertAirportContacts\r\n\t\t};\r\n\r\n /**\r\n * Extend an array of Objects from the default airportContact Object\r\n * @memberof AirportContactFactory\r\n * @param {Array} objList an Array Of airportContact\r\n * @returns {Array} airportContact\r\n */\r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericService.fromObjectList(objList,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Get airportContacts\r\n * @memberof AirportContactFactory\r\n * @returns {Array} airportContacts\r\n */\r\n\t\tfunction getAirportContactsFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Save airportContacts to storage\r\n * @memberof AirportContactFactory\r\n * @param {Array} airportContacts A list of AirportContacts\r\n */\r\n\t\tfunction setAirportContactsToStorage(airportContacts) {\r\n\t\t\tGenericService.saveAll(airportContacts,objType,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Remove the airportContacts of the local storage\r\n * @memberof AirportContactFactory\r\n */\r\n\t\tfunction clearAirportContactsFromStorage() {\r\n\t\t\tGenericService.removeAll(objType,objCallback);\r\n }\r\n \r\n /**\r\n * Get the contacts for a given airport\r\n * @memberof AirportContactFactory\r\n */\r\n\t\tfunction getAirportContacts(airportIata) {\r\n var all = this.getAirportContactsFromStorage();\r\n if (!all) return null;\r\n var airport = all.filter(function(item){return item.Iata == airportIata;});\r\n if (!airport || airport.length == 0) return null;\r\n //we expect a single airport item per iata\r\n return airport[0];\r\n //return GenericService.fromObjectList(airport[0].Contacts, Contact);\r\n }\r\n\r\n /**\r\n * Upsert airport contacts\r\n * @memberof AirportContactFactory\r\n */\r\n function upsertAirportContacts(airportContacts){\r\n var newStations = airportContacts.map(x=>x.Iata);\r\n var contactsLS = this.getAirportContactsFromStorage();\r\n contactsLS = contactsLS.filter(x => !newStations.includes(x.Iata));\r\n var updatedContactList = contactsLS.concat(airportContacts);\r\n setAirportContactsToStorage(updatedContactList);\r\n }\r\n \r\n\treturn service;\r\n\t}\r\n\r\n \r\n })(); ","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('AirportHotelFactory',AirportHotelFactory);\r\n \r\n /**\r\n * @memberof PilotReports\r\n * @ngdoc factory\r\n * @name AirportHotelFactory\r\n * @description \r\n * Add, Update, Delete and Get Airport Hotels.\r\n * @ngInject\r\n */\r\nfunction AirportHotelFactory(GenericService){\r\n \r\n /**\r\n * Initialize the AirportHotel\r\n * @memberof AirportHotelFactory\r\n */\r\n\t\tfunction Airport() {\r\n this.Iata=null;\r\n this.Hotels=null;\r\n }\r\n \r\n\t\tvar objType = 'airportHotels';\r\n\t\tvar objCallback = Airport; \r\n\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tgetAirportHotelsFromStorage : getAirportHotelsFromStorage,\r\n\t\t\tsetAirportHotelsToStorage : setAirportHotelsToStorage,\r\n clearAirportHotelsFromStorage : clearAirportHotelsFromStorage,\r\n getAirportHotels: getAirportHotels,\r\n upsertAirportHotels : upsertAirportHotels\r\n\t\t};\r\n\r\n /**\r\n * Extend an array of Objects from the default airportHotel Object\r\n * @memberof AirportHotelFactory\r\n * @param {Array} objList an Array Of airportHotel\r\n * @returns {Array} airportHotel\r\n */\r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericService.fromObjectList(objList,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Get airportHotels\r\n * @memberof AirportHotelFactory\r\n * @returns {Array} airportHotels\r\n */\r\n\t\tfunction getAirportHotelsFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Save airportHotels to storage\r\n * @memberof AirportHotelFactory\r\n * @param {Array} airportHotels A list of AirportHotels\r\n */\r\n\t\tfunction setAirportHotelsToStorage(airportHotels) {\r\n\t\t\tGenericService.saveAll(airportHotels,objType,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Remove the airportHotels of the local storage\r\n * @memberof AirportHotelFactory\r\n */\r\n\t\tfunction clearAirportHotelsFromStorage() {\r\n\t\t\tGenericService.removeAll(objType,objCallback);\r\n }\r\n \r\n /**\r\n * Get the Hotels for a given airport\r\n * @memberof AirportHotelFactory\r\n */\r\n\t\tfunction getAirportHotels(airportIata, fltDate) {\r\n var all = this.getAirportHotelsFromStorage();\r\n if (!all) return null;\r\n var airport = all.filter(function(item){return item.Iata == airportIata});\r\n if (!airport || airport.length == 0) return null;\r\n \r\n //for each airport hotel\r\n //from all available hotel priorities, find the one matching the active period \r\n angular.forEach(airport[0].Hotels, function(hotel) \r\n {\r\n var fltActiveHotels = hotel.HotelPriorities.filter(function(item){return fltDate >= item.ActiveBegin && fltDate <= item.ActiveEnd}); \r\n if (!fltActiveHotels || fltActiveHotels.length == 0) return; //hotel inactive in FltDate - ActivePriority will be undefined for this hotel\r\n hotel.ActivePriority = fltActiveHotels[0].PriorityNo; //set the ActivePriority field for the hotel to be displayed in UI\r\n });\r\n \r\n\r\n //we expect a single airport item per iata\r\n return airport[0];\r\n //return GenericService.fromObjectList(airport[0].Hotels, Hotel);\r\n }\r\n\r\n /**\r\n * Upsert aircraft hotels\r\n * @memberof AirportHotelFactory\r\n */\r\n function upsertAirportHotels(airportHotels) {\r\n var newHotels = airportHotels.map(x => x.Iata);\r\n var hotelsLS = this.getAirportHotelsFromStorage();\r\n hotelsLS = hotelsLS.filter(x => !newHotels.includes(x.Iata));\r\n var updatedHotelsList = hotelsLS.concat(airportHotels);\r\n setAirportHotelsToStorage(updatedHotelsList);\r\n }\r\n \r\n\treturn service;\r\n\t}\r\n\r\n \r\n })(); ","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('BucketCtrl', BucketCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name BucketCtrl\r\n * @description \r\n * View bucket\r\n * @ngInject\r\n */\r\n function BucketCtrl($scope, $location, BucketFactory, UserFactory, MessageFactory, $timeout, SettingsMain, defaultBucketDate) {\r\n\r\n var ownDuties = [];\r\n var sharedDuties = [];\r\n var approvedDuties = [];\r\n\r\n $scope.state = 'bucketCalendar';\r\n var user = UserFactory.getUser();\r\n $scope.isSecure = UserFactory.isSecure();\r\n $scope.isUserSA = user.position == 'SA' ? true : false;\r\n $scope.logged_user_info = user.aimsId + ' - ' + user.name;\r\n $scope.getCalendarData = getCalendarData;\r\n $scope.showErrorMessage = false;\r\n\r\n var selectedDate = SettingsMain.getCalendarSelectedDate(); //Redirect to month that was previously selected\r\n SettingsMain.setCalendarSelectedDate(null); //Then reinitialize to current month\r\n\r\n getCalendarData();\r\n\r\n function getCalendarData(){\r\n progressBarBox(true);\r\n BucketFactory.getDutyObject(function (responseData) {\r\n ownDuties = responseData.data.data.Duties;\r\n sharedDuties = responseData.data.data.SharedDuties;\r\n approvedDuties = responseData.data.data.ApprovedDuties;\r\n setupView();\r\n progressBarBox(false);\r\n }).catch(function(error) {\r\n $scope.showErrorMessage = true;\r\n progressBarBox(false);\r\n console.error('Load duties error', error.status, error.statusText);\r\n });\r\n }\r\n \r\n function setupView() {\r\n if (!UserFactory.isLoggedIn()) {\r\n $location.path(\"/login\");\r\n }\r\n \r\n $scope.number_of_messages = MessageFactory.getMessagesFromStorage().length;\r\n $scope.number_of_messages_not_readen = MessageFactory.getCountOfUnreadMessages();\r\n\r\n\r\n /*var ownEvents = formatDuties(ownDuties, true, false);\r\n if (sharedDuties.length > 0) {\r\n var sharedEvents = formatDuties(sharedDuties, false, false);\r\n var events = ownEvents.concat(sharedEvents);\r\n } else {\r\n var events = ownEvents;\r\n }*/\r\n $scope.notification = createNotification(ownDuties);\r\n var ownEvents = formatDuties(ownDuties, true, false);\r\n var events = ownEvents;\r\n if(approvedDuties != null || approvedDuties!= undefined){\r\n if(approvedDuties.length>0){\r\n var appvovedEvents = formatDuties(approvedDuties, true, true);\r\n var events = events.concat(appvovedEvents);\r\n }\r\n }\r\n calendar(events);\r\n }\r\n\r\n\r\n /**\r\n * Transform routes in calendar events\r\n * @memberof BucketCtrl\r\n * @param {array} routes - The Scheduled Routes \r\n * @return {array} events \r\n */\r\n function formatDuties(duties, isOwnDuty, isApproved) {\r\n var dutiesEvents = [];\r\n for (var i = 0; i < duties.length; i++) {\r\n \r\n if(duties[i].IsUpdated){\r\n console.log(duties[i]);\r\n }\r\n /*************** Add main event for duty *********************/\r\n\r\n // var eType = (isOwnDuty ? 'own-' : 'shared-') + duties[i].DutyType.toLowerCase();\r\n var eClassName = getEventClassName(duties[i], isOwnDuty, isApproved);\r\n var eIcons = getEventIcons(duties[i], isOwnDuty, isApproved);\r\n var eTitle = getEventTitle(duties[i], isOwnDuty) + ((duties[i].TotalSharedDuties == undefined) ? \"\" : duties[i].TotalSharedDuties) ;\r\n var eOtherInfos = getOtherInfos(duties[i], isOwnDuty);\r\n var event = {\r\n _id: duties[i].Id,\r\n // type: eType,\r\n icons: eIcons,\r\n className: eClassName.class,\r\n title: eTitle,\r\n start : (duties[i].DutyBegin == duties[i].DutyEnd)? duties[i].DutyDateS :duties[i].DutyBegin,\r\n\t\t\t\t end : (duties[i].DutyBegin == duties[i].DutyEnd)? null : duties[i].DutyEnd,\r\n sortOrder: (isOwnDuty ? 1 : -1),\r\n otherInfos: eOtherInfos,\r\n shareable: duties[i].Shareable,\r\n isOwnDuty: isOwnDuty,\r\n isApproved: isApproved,\r\n isOwnApproved: duties[i].HasApprovedProposals,\r\n listViewColor: eClassName.color\r\n }\r\n dutiesEvents.push(event);\r\n\r\n }\r\n return dutiesEvents;\r\n }\r\n \r\n function createNotification(duties){\r\n var NewPendingProposalsCount = 0;\r\n var NewApprovedProposalsCount = 0;\r\n var NewRejectedProposalsCount = 0;\r\n var notificationText = null;\r\n \r\n for (var i = 0; i < duties.length; i++) {\r\n \r\n if(duties[i].IsUpdated){\r\n if(duties[i].HasApprovedProposals){\r\n NewApprovedProposalsCount++;\r\n }else{\r\n NewPendingProposalsCount += duties[i].NewPendingProposalsCount;\r\n NewRejectedProposalsCount += duties[i].NewRejectedProposalsCount;\r\n }\r\n }\r\n }\r\n \r\n /* var notification = {\r\n NewPendingProposalsCount : NewPendingProposalsCount,\r\n NewApprovedProposalsCount : NewApprovedProposalsCount,\r\n NewRejectedProposalsCount : NewRejectedProposalsCount\r\n }*/\r\n \r\n if((NewPendingProposalsCount + NewApprovedProposalsCount + NewRejectedProposalsCount)>0){\r\n notificationText = \"You have \"\r\n var hasPrevious = false;\r\n if(NewPendingProposalsCount){\r\n notificationText = notificationText + NewPendingProposalsCount + \" pending\";\r\n hasPrevious = true;\r\n }\r\n \r\n if(NewRejectedProposalsCount){\r\n var conjuction = (hasPrevious ? NewApprovedProposalsCount ? \", \" : \" and \" : \"\");\r\n notificationText = notificationText + conjuction + NewRejectedProposalsCount + \" rejected\";\r\n hasPrevious = true;\r\n }\r\n \r\n if(NewApprovedProposalsCount){\r\n var conjuction = (hasPrevious ? \" and \" : \"\" );\r\n notificationText = notificationText + conjuction + NewApprovedProposalsCount + \" accepted\";\r\n }\r\n \r\n notificationText = notificationText+ \" proposals.\" ; \r\n \r\n \r\n }\r\n \r\n \r\n \r\n return notificationText;\r\n \r\n }\r\n \r\n /**\r\n * Returns an array of strings for icons to display in the event tile\r\n * @memberof BucketCtrl\r\n * @param {object} duty - The Scheduled duty \r\n * @param {boolean} ownDuty - Is set to true when the duty is current user's duty, otherwise is set to false\r\n * @return {array} icons - The array of strings for icons to display in the event tile.\r\n */\r\n function getEventIcons(duty, isOwnDuty, isApproved) {\r\n var icons = [];\r\n if (!isOwnDuty) \r\n icons.push('fa-sing-in');\r\n else{\r\n if (duty.IsUpdated) icons.push('fa-star text-orange');\r\n\r\n /* if (duty.PendingProposalsCount > 0 && !isApproved) icons.push('fa-info-circle');*/\r\n if (!duty.Shareable || isApproved) icons.push('fa-lock');\r\n if (duty.Shared && !isApproved) icons.push('fa-bitbucket');\r\n\r\n \r\n\r\n }\r\n return icons;\r\n }\r\n\r\n /**\r\n * Returns the title for the event tile\r\n * @memberof BucketCtrl\r\n * @param {object} duty - The Scheduled duty \r\n * @param {boolean} ownDuty - Is set to true when the duty is current user's duty, otherwise is set to false\r\n * @return {string} title - The title to display in the event tile.\r\n */\r\n function getEventTitle(duty, isOwnDuty) {\r\n var title = '';\r\n if (isOwnDuty) title += duty.Title;\r\n else title += 'Shared duties: ';\r\n return title;\r\n }\r\n\r\n /**\r\n * Returns the class for the event tile\r\n * @memberof BucketCtrl\r\n * @param {object} duty - The Scheduled duty \r\n * @param {boolean} ownDuty - Is set to true when the duty is current user's duty, otherwise is set to false\r\n * @return {string} className - The class(es) to use for displaying the event tile.\r\n */\r\n function getEventClassName(duty, isOwnDuty, isApproved) {\r\n var eventClass = {class:'fc-bucket ', color:''};\r\n if (isOwnDuty) {\r\n eventClass.class += 'fc-own ';\r\n var hasApprovedTrade = duty.HasApprovedProposals;\r\n if(isApproved == true) {\r\n eventClass.class += 'fc-green-inverted ';\r\n eventClass.color = 'lv-green-inverted';\r\n }\r\n else if (hasApprovedTrade) {\r\n eventClass.class += 'fc-green ';\r\n eventClass.color = 'lv-green';\r\n }\r\n else if (duty.Shared) {\r\n eventClass.class += 'fc-primary-inverted ';\r\n eventClass.color = 'lv-blue';\r\n }\r\n /* else if (duty.Shareable && duty.PendingProposalsCount == 0) {\r\n eventClass.class += 'fc-blue ';\r\n eventClass.color = 'lv-blue';\r\n } else if (duty.PendingProposalsCount > 0) {\r\n eventClass.class += 'fc-orange ';\r\n eventClass.color = 'lv-orange';\r\n } else if (duty.Bookmarks != undefined && duty.Bookmarks.length > 0) {\r\n eventClass.class += 'fc-purple-inverted ';\r\n eventClass.color = 'lv-purple-inverted';\r\n } */\r\n else {\r\n eventClass.class += 'fc-white ';\r\n eventClass.color = 'lv-white';\r\n }\r\n } else {\r\n eventClass.class += 'fc-aluminum ';\r\n eventClass.color = 'lv-aluminum';\r\n }\r\n return eventClass;\r\n }\r\n\r\n /**\r\n * Returns an array of objects for infos (label, number) to display in the event tile\r\n * @memberof BucketCtrl\r\n * @param {object} duty - The Scheduled duty \r\n * @param {boolean} ownDuty - Is set to true when the duty is current user's duty, otherwise is set to false\r\n * @return {array} infos - The array of objects for infos (label, number) to display in the event tile.\r\n */\r\n function getOtherInfos(duty, isOwnDuty) {\r\n var infos = [];\r\n if (isOwnDuty) {\r\n var hasApprovedTrade = duty.HasApprovedProposals;\r\n\r\n if (!hasApprovedTrade) {\r\n if (duty.PendingProposalsCount > 0) infos.push({ label: 'Proposals', num: duty.PendingProposalsCount });\r\n if (duty.BookmarksCount > 0) infos.push({ label: 'Bookmarks', num: duty.BookmarksCount });\r\n\r\n // var totalBookmarks = (duty.bookmarks == undefined ? 0 : duty.bookmarks.length);\r\n // if (totalBookmarks > 0) infos.push({ label: 'Bookmarks', num: totalBookmarks.toString() });\r\n }\r\n }\r\n // else {\r\n // if (duty.TotalSharedDuties > 0) infos.push({ label: 'Total', num: duty.TotalSharedDuties.toString() });\r\n // //if (duty.unclaimedShared > 0) infos.push({ label: 'Unclaimed', num: duty.unclaimedShared.toString() });\r\n // }\r\n return infos;\r\n }\r\n\r\n function calendar(events) {\r\n $('#calendar').fullCalendar('destroy');\r\n \r\n $(\"#calendar\").fullCalendar({\r\n defaultView: getDefaultView(),\r\n defaultDate: defaultBucketDate,\r\n firstDay: 1,\r\n lang: 'en',\r\n editable: false,\r\n draggable: false,\r\n selectable: false,\r\n selectHelper: false,\r\n unselectAuto: false,\r\n disableResizing: false,\r\n droppable: false,\r\n fixedWeekCount: false,\r\n nextDayThreshold: \"00:00:00\",\r\n header: {\r\n left: 'title',\r\n center: '',\r\n\t\t\t\t\tright: 'month,listMonth today prev,next'\r\n },\r\n timeFormat: 'HH:mm',\r\n displayEventEnd: true,\r\n events: events,\r\n eventOrder: \"sortOrder\",\r\n eventRender: function (event, element, icon) {\r\n element.find('.fc-title').prepend(\"
\");\r\n if($('#calendar').fullCalendar('getView').type === 'listMonth'){\r\n element.find('.fc-list-item-title').addClass('listview-icon');\r\n $.each(event.className, function (index, icon) {\r\n element.addClass(event.listViewColor);\r\n });\r\n $.each(event.icons, function (index, icon) {\r\n element.find('.listview-icon').prepend(\" \");\r\n });\r\n \r\n if (event.otherInfos != null && event.otherInfos.length > 0) {\r\n $.each(event.otherInfos, function (index, info) {\r\n if(info.label == 'Proposals')\r\n element.find('.fc-list-item-title').append(\"\" + info.num + \"\");\r\n });\r\n \r\n }\r\n }\r\n else{\r\n if (event.icons != null && event.icons.length > 0) {\r\n \r\n element.find('.fc-title').prepend(\"\");\r\n $.each(event.icons, function (index, icon) {\r\n element.find('.calendar-icon').append(\" \");\r\n });\r\n }\r\n if (event.otherInfos != null && event.otherInfos.length > 0) {\r\n $.each(event.otherInfos, function (index, info) {\r\n element.find('.fc-title').append(\"
\" + info.label + \": \" + info.num + \"
\");\r\n element.find('.fc-list-item-title').add(\"\" + info.num + \"\");\r\n });\r\n \r\n }\r\n }\r\n },\r\n eventResize: function(event, delta, revertFunc) {\r\n changeView(detectMobile(),'#calendar');\r\n },\r\n dayRender: function (date, cell) {\r\n },\r\n // dayClick: function(date, jsEvent, view) {\r\n // $timeout(function(){ gotoDayBucketView(date); })\r\n // },\r\n eventClick: function (calEvent, jsEvent, view) {\r\n if(calEvent.shareable == true && calEvent.isOwnDuty && (!calEvent.isApproved || calEvent.isOwnApproved)){\r\n $timeout(function () { gotoDayBucketView(calEvent._id); });\r\n }\r\n else if(calEvent.shareable == false && calEvent.isOwnDuty)\r\n {\r\n if(!calEvent.isApproved){ //don't allow click for approved duty\r\n $timeout(function () { unableShare(); });\r\n }\r\n }\r\n },\r\n height: 'auto'\r\n });\r\n \r\n $('.fc-listMonth-button').click(function(){\r\n SettingsMain.setCalendarViewStyle('listMonth');\r\n })\r\n \r\n $('.fc-month-button').click(function(){\r\n SettingsMain.setCalendarViewStyle('month');\r\n })\r\n\r\n if(selectedDate != null && selectedDate != undefined){\r\n $(\"#calendar\").fullCalendar('gotoDate', selectedDate);\r\n }\r\n }\r\n\r\n function getDefaultView(){\r\n var calendarStyle = SettingsMain.getCalendarViewStyle();\r\n if (calendarStyle == null){\r\n calendarStyle = detectMobile() ? \"listMonth\" : \"month\";\r\n }\r\n return calendarStyle;\r\n \r\n }\r\n \r\n\t\t\tfunction detectMobile() {\r\n\t\t\t\tvar isMobile =(window.innerWidth <= 800 && window.innerHeight <= 735); \r\n \r\n return isMobile;\t\t\r\n }\t\r\n \r\n \r\n\r\n /**\r\n * Redirects to bucket calendar day \r\n * @memberof BucketCtrl\r\n */\r\n function gotoDayBucketView(dutyId) {\r\n $location.path('/bucketDay/' + dutyId);\r\n }\r\n }\r\n function unableShare(){\r\n bootbox.dialog({\r\n message: \"
You can't share this duty, please try another shareable duty.
\",\r\n title: \"Warning\",\r\n buttons: {\r\n cancel:{\r\n label: \"Close\",\r\n className: \"btn-default\",\r\n callback: function(){}\r\n }\r\n }\r\n })\r\n }\r\n function progressBarBox( isOpen ){\r\n if(isOpen){\r\n bootbox.dialog({\r\n closeButton: false,\r\n message: '
Please wait...
',\r\n //title: \"Please wait...\"\r\n });\r\n }else {\r\n bootbox.hideAll();\r\n }\r\n\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n a3_cabin_reports.factory('BucketFactory', BucketFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name BucketFactory\r\n * @description \r\n * Get Duties from API \r\n * @ngInject\r\n */\r\n function BucketFactory(GenericService, $http, $q, apiUrl, LogService) {\r\n\r\n /**\r\n * Initialize Bucket\r\n * @memberof BucketFactory\r\n */\r\n \r\n var service = {\r\n getDutyObject: getDutyObject,\r\n getDutyById: getDutyById,\r\n shareDuty: shareDuty,\r\n acknowledgeProposal : acknowledgeProposal,\r\n fetchProposal: fetchProposal,\r\n createProposal: createProposal,\r\n evaluateProposal: evaluateProposal,\r\n undoProposalStatus: undoProposalStatus,\r\n fetchSharedProposal: fetchSharedProposal\r\n };\r\n\r\n \r\n /**\r\n * Gets Bucket Calendar object\r\n * @memberof BucketFactory\r\n * @param {function} callback \r\n */\r\n function getDutyObject(callback) {\r\n return $http.get(apiUrl + '/bucket/', { 'Content-Type': 'application/json' })\r\n .then(callback);\r\n }\r\n\r\n /**\r\n * Gets duty object and shared duties object for the BucketDay View\r\n * @memberof BucketFactory\r\n * @param {number} dutyId \r\n * @param {function} callback \r\n */\r\n function getDutyById(dutyId, callback){\r\n return $http.get(apiUrl + '/bucket/GetBucketDuty/' + dutyId, { 'Content-Type': 'application/json' })\r\n .then(callback);\r\n }\r\n \r\n /**\r\n * Shares/Unshares duty\r\n * @memberof BucketFactory\r\n * @param {object} duty \r\n * @param {function} callback \r\n * @param {function} errorCallback \r\n */\r\n function shareDuty(duty, callback, errorCallback ){\r\n //todo remove when api became correct\r\n var dutyMinified = {\r\n Id: duty.Id,\r\n Shareable: duty.Shareable,\r\n Shared: duty.Shared,\r\n Comments: duty.Comments,\r\n CrewInformation: {\r\n Email: null,\r\n Phone: null,\r\n Comments: null\r\n }\r\n };\r\n\r\n return $http.post(apiUrl + '/bucket/ShareDuty/', dutyMinified, {'Content-Type' : 'application/json' })\r\n .then (callback)\r\n .catch(errorCallback);\r\n }\r\n\r\n /**\r\n * Makes proposal acknowledged \r\n * @memberof BucketFactory\r\n * @param {number} proposalId \r\n * @param {function} callback \r\n */\r\n function acknowledgeProposal(proposalId, callback){\r\n return $http.get(apiUrl + '/bucket/AcknowledgeProposal?proposalId=' + proposalId, { 'Content-Type' : 'application/json' })\r\n .then(callback);\r\n }\r\n\r\n /**\r\n * Fetches proposal info \r\n * @memberof BucketFactory\r\n * @param {number} dutyId \r\n * @param {function} callback \r\n * @returns {object} - Promise containing Proposed and Requested duties alongside Crew and Route details for each one\r\n */\r\n function fetchProposal(dutyId, callback){\r\n return $http.get(apiUrl + '/bucket/FetchProposal?id=' + dutyId, { 'Content-Type' : 'application/json' })\r\n .then(callback);\r\n }\r\n\r\n /**\r\n * Fetches shared proposal info\r\n * @param {number} dutyId \r\n * @param {number} sharedDutyId \r\n * @param {function} callback\r\n * @returns {object} - Promise containing Proposed and Requested duties alongside Crew and Route details for each one\r\n */\r\n function fetchSharedProposal(dutyId, sharedDutyId, callback){\r\n return $http.get(apiUrl + '/bucket/FetchSharedProposal?dutyId=' + dutyId + '&sharedDutyId=' + sharedDutyId, { 'Content-Type' : 'application/json' })\r\n .then(callback);\r\n }\r\n\r\n /**\r\n * Creates/Sends Proposal\r\n * @memberof BucketFactory\r\n * @param {object} proposal - Containing proposedDutiesIdList and requestedDutiesIdList\r\n * @param {function} callback\r\n * @returns {object} - Promise containing updated proposal \r\n */\r\n function createProposal(proposal, callback){\r\n return $http.post(apiUrl + '/bucket/CreateProposal', proposal, { 'Content-Type' : 'application/json' })\r\n .then(callback);\r\n }\r\n\r\n /**\r\n * Approves/Rejects proposal\r\n * @memberof BucketFactory\r\n * @param {object} proposal - Containing Id and isApproved\r\n * @param {function} callback\r\n * @returns {object} - Promise containing updated proposal \r\n */\r\n function evaluateProposal(proposal, callback){\r\n return $http.put(apiUrl + '/bucket/EvaluateProposal/' + proposal.Id, proposal.isApproved, { 'Content-Type' : 'application/json' })\r\n .then(callback);\r\n }\r\n\r\n /**\r\n * Reverts proposal to previous status\r\n * @memberof BucketFactory\r\n * @param {number} proposalId \r\n * @param {function} callback \r\n * @returns {object} - Promise containing updated proposal\r\n */\r\n function undoProposalStatus(proposalId, callback){\r\n return $http.put(apiUrl + '/bucket/UndoProposalStatus/' + proposalId, { 'Content-Type' : 'application/json' })\r\n .then(callback);\r\n }\r\n\r\n return service;\r\n }\r\n})();","(function(){\r\n 'use strict';\r\n\r\na3_cabin_reports.controller('BucketDayCtrl', BucketDayCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name BucketDayCtrl\r\n * @description \r\n * Shows the Bucket Day informations\r\n * @ngInject\r\n */\r\n\r\n function BucketDayCtrl($scope, BucketFactory, $routeParams, $location, $uibModal, UserFactory, SettingsMain, $timeout) {\r\n $scope.isSharedLate = false;\r\n $scope.selectedStates = \"Shared, Pending\"; \r\n\r\n \r\n /**\r\n * Checks if duty wont be approved in time because of the weekend \r\n * @memberof BucketDayCtrl\r\n */\r\n function checkLateShare() {\r\n var today = new Date();\r\n var dutyDay = new Date($scope.duty.DutyBegin);\r\n\r\n // how many days until duty date\r\n var trimmedToday = new Date(today);\r\n var trimmedDutyDay = new Date(dutyDay);\r\n var diffDays = Date.DifferenceInDays(trimmedToday.trimTime(), trimmedDutyDay.trimTime());\r\n\r\n //friday saturday sunday\r\n var fss = [5, 6, 0];\r\n //saturday sunday monday\r\n var ssm = [6, 0, 1]\r\n\r\n // today is Fr,Sa,Su AND duty on Sa,Su,Mo AND same weekend\r\n if (fss.contains(today.getDay()) && ssm.contains(dutyDay.getDay()) && diffDays < 4){\r\n //friday before 14:00 is not a late share\r\n if (!(today.getDay() == 5 && today.getUTCHours() < 14))\r\n $scope.isSharedLate = true;\r\n }\r\n }\r\n\r\n $scope.currentDutyId = dutyId;\r\n \r\n $scope.initialized = false;\r\n \r\n $scope.displayMessage = displayMessage;\r\n $scope.confirmUnshare = confirmUnshare;\r\n $scope.shareDuty = shareDuty;\r\n $scope.isLoading = false;\r\n\r\n var dutyId = $routeParams.dutyId;\r\n $scope.currentDutyId = dutyId;\r\n \r\n \r\n \r\n var user = UserFactory.getUser();\r\n $scope.activeTab = 0;\r\n \r\n \r\n $scope.duty = null;\r\n $scope.Duties = [];\r\n $scope.proposals = [];\r\n \r\n $scope.toggle = {\r\n Accepted:true,\r\n Rejected:false,\r\n Pending:true,\r\n Bookmarks:true\r\n }\r\n \r\n $scope.getProposalBorderStyle = getProposalBorderStyle;\r\n \r\n function getProposalBorderStyle(proposal){\r\n var textclass=\"\";\r\n if(proposal.Status == \"Pending\" && proposal.State == 'Out' ){\r\n textclass=\"border-left-light-blue\";\r\n }else if(proposal.Status == \"Rejected\" || proposal.Status == \"RejectedBySTP\"){\r\n textclass=\"border-left-red\";\r\n }else if(proposal.Status == \"Pending\" && proposal.State == 'In'){\r\n textclass=\"border-left-orange\";\r\n }else if(proposal.Status == \"Approved\" || proposal.Status == \"ApprovedBySTP\" ){\r\n textclass=\"border-left-green\";\r\n } else if( proposal.Status == \"Shared\"){\r\n textclass=\"border-left-blue-gray\";\r\n }\r\n return textclass;\r\n } \r\n \r\n \r\n $scope.logged_user_info = user.aimsId + ' - ' + user.name;\r\n\r\n \r\n $scope.hasTimeChange = false;\r\n \r\n $scope.approvedDuty = null;\r\n $scope.showMobileProposalCriteria = false;\r\n \r\n $scope.filterProposal = filterProposal;\r\n $scope.hasProposals = hasProposals;\r\n \r\n function hasProposals(){\r\n var value = false;\r\n if($scope.duty && $scope.duty.Duties){\r\n for(var i=0;i<$scope.duty.Duties.length;i++) { \r\n if($scope.duty.Duties[i].Id>0){\r\n value = true;\r\n break;\r\n }\r\n }\r\n if(!value && $scope.activeTab != 1 ) {\r\n $scope.activeTab = 1;\r\n }\r\n }\r\n return value;\r\n }\r\n \r\n function filterProposal(proposal){\r\n var isShown = false;\r\n///ng-if=\"proposal.Id >0 && filterProposal(proposal)\"\r\n if (proposal.Id>0){\r\n if(proposal.Status == \"Approved\" || proposal.Status == \"ApprovedBySTP\" ){\r\n $scope.approvedDuty = true;\r\n if($scope.toggle.Accepted)\r\n isShown = true;\r\n }else if(proposal.Status == \"Pending\" && $scope.toggle.Pending){\r\n isShown = true;\r\n }else if((proposal.Status == \"Rejected\" || proposal.Status == \"RejectedBySTP\") && ($scope.toggle.Rejected || !proposal.isAcknowledged)){\r\n isShown = true;\r\n }else if(proposal.Status == \"Bookmarked\" && $scope.toggle.Bookmarks){\r\n isShown = true;\r\n }\r\n } \r\n \r\n return isShown;\r\n }\r\n\r\n \r\n $scope.returnToBucket = returnToBucket;\r\n\r\n $scope.refresh = getData;\r\n \r\n getData();\t\r\n \r\n function getData(){\r\n $scope.isLoading = true;\r\n BucketFactory.getDutyById(dutyId, function(responseData){ \r\n $scope.initialized = true;\r\n $scope.isLoading = false;\r\n $scope.duty = responseData.data.data.duty;\r\n $scope.currentDutyDate = $scope.duty.DutyDateS;\r\n $scope.Duties = responseData.data.data.duty.Duties;\r\n $scope.totalItems = $scope.Duties.length;\r\n $scope.currentPage = 1;\r\n\r\n SettingsMain.setCalendarSelectedDate($scope.currentDutyDate);\r\n \r\n checkLateShare();\r\n initProposalsView();\r\n \r\n }).catch(function(error) {\r\n $scope.isLoading = false;\r\n console.error('Wrong AimsId', error.status, error.statusText);\r\n returnToBucket();\r\n });\r\n }\r\n\r\n function initProposalsView(){\r\n $scope.approvedDuty = false; \r\n for(var i=0;i<$scope.duty.Duties.length;i++) { \r\n if($scope.duty.Duties[i].Status == \"Approved\" || $scope.duty.Duties[i].Status == \"ApprovedBySTP\" ){ \r\n $scope.approvedDuty = true; \r\n }\r\n }\r\n } \r\n\r\n /**\r\n * Opens a dialog with information on a duty, \r\n * Depending on the duty type (in proposal, out proposal or shared by other in bucket) different options are displayed:\r\n * 1. In proposal\r\n * - Approve (available when in proposal not reviewed, will set status to Approved)\r\n * - Reject (available when in proposal not reviewed, will set status to Rejected)\r\n * - Reset (available when in proposal has been reviewed, will set status to Pending)\r\n * - Close (available always, just closes dialog, no action performed)\r\n * 2. Out proposal\r\n * - Remove (available when out proposal not reviewed, will remove request from duty)\r\n * - Close (available always, just closes dialog, no action performed)\r\n * 3. Shared in bucket\r\n * - Request (available always, will send a request for duty, will be added in out proposals)\r\n * - Close (available always, just closes dialog, no action performed)\r\n * @memberof BucketCtrl\r\n */\r\n\r\n \r\n /**\r\n * Prompts user to confirm sharing duty, if user agrees then the duty dialog will open \r\n * @memberof BucketCtrl\r\n */\r\n function shareDuty(duty) {\r\n //if (confirm('You are about to share into global bucket the selected duty. Do you wish to continue?')) {\r\n duty.fromShareBtn = true;\r\n \r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgDuty.html',\r\n controller: 'BucketModalCtrl',\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n duty: function () { return duty; },\r\n currentDutyId: function () { return dutyId; }\r\n }\r\n });\r\n \r\n modalInstance.result.then(function (refresh) {\r\n if(refresh){\r\n getData();\r\n }\r\n });\r\n //}\r\n }\r\n\r\n /**\r\n * Prompts user to confirm removing duty from shared bucket, if user agrees then all proposal for the duty will be removed (will be displayed as N/A to other users) \r\n * @memberof BucketCtrl\r\n */\r\n\r\n function confirmUnshare() {\r\n bootbox.dialog({\r\n message: \"Please confirm that you wish to Un-share your duty.

\",\r\n title: \"Unshare\",\r\n buttons: {\r\n confirm:{\r\n label: ' Confirm',\r\n className: \"btn-warning\",\r\n callback: function(){\r\n BucketFactory.shareDuty($scope.duty, function(responseData){ \r\n $scope.responseText = responseData.data.data;\r\n getData();\r\n })\r\n }\r\n }, \r\n cancel:{\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function(){}\r\n }\r\n }\r\n })\r\n } \r\n\r\n /**\r\n * Redirects to bucket' calendar\r\n * @memberof BucketCtrl\r\n */\r\n function returnToBucket() {\r\n SettingsMain.setEditingPage(null);\r\n $location.path(\"/bucket/\");\r\n }\r\n /**\r\n * Redirects to flights' calendar\r\n * @memberof BucketCtrl\r\n */\r\n function gotoFlightsCalendar() {\r\n SettingsMain.setEditingPage(null);\r\n $location.path(\"/\");\r\n }\r\n \r\n \r\n //Pagination\r\n\t\t$scope.pageOptions = [\r\n\t\t\t\t{ name: '5', value: '5' }, \r\n\t\t\t\t{ name: '8', value: '8' }, \r\n\t\t\t\t{ name: '15', value: '15' },\r\n\t\t\t\t{ name: '30', value: '30' },\r\n\t\t\t\t{ name: '50', value: '50' }\r\n\t\t];\r\n \r\n\t\t$scope.viewby = $scope.pageOptions[1].value;\r\n\t\t$scope.currentPage = 1;\r\n\t\t$scope.itemsPerPage = $scope.viewby;\r\n\t\t$scope.maxSize = 5; //Number of pager buttons to show\r\n\t\t$scope.setPage = setPage;\r\n\t\t$scope.setItemsPerPage = setItemsPerPage;\r\n\r\n\r\n /**\r\n * Set pagination page number\r\n * @memberof BucketDayCtrl\r\n * @param {number} pageNo list page number\r\n */\r\n\t\tfunction setPage(pageNo) {\r\n\t\t\t$scope.currentPage = pageNo;\r\n\t\t}\r\n /**\r\n * Set items per page \r\n * @memberof BucketDayCtrl\r\n * @param {number} num the Number of items to show per page\r\n */\r\n\t\tfunction setItemsPerPage(num) {\r\n\t\t\t$scope.itemsPerPage = num;\r\n\t\t\t$scope.currentPage = 1; //reset to first page\r\n\t\t}\r\n \r\n \r\n function displayMessage(message, hasErrors) {\r\n $scope.showResponse = true;\r\n $scope.responseText = message;\r\n $scope.responseHasErrors = hasErrors;\r\n $timeout(function () {if(!hasErrors){$scope.showResponse = false;}} , 1000);\r\n }\r\n \r\n \r\n\r\n}\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('BucketModalCtrl', BucketModalCtrl)\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name BucketModalCtrl\r\n * @description \r\n * Shows Share/Unshare Modal \r\n * @ngInject\r\n */\r\n\r\n function BucketModalCtrl($scope, $timeout, $uibModalInstance, duty, currentDutyId, BucketFactory){\r\n $scope.duty = duty;\r\n $scope.currentDutyId = currentDutyId;\r\n $scope.closeDuty = closeDuty;\r\n\r\n $scope.shareDuty = shareDuty;\r\n $scope.responseText = null;\r\n $scope.responseHasErrors = null;\r\n\r\n $scope.submitted = false;\r\n\r\n /**\r\n * Close the modal\r\n * @memberof BucketModalCtrl\r\n */\r\n function closeDuty(refresh){\r\n $uibModalInstance.close(refresh);\r\n }\r\n\r\n /**\r\n * Adds/Removes duty to/from global bucket\r\n * @memberof BucketModalCtrl\r\n */\r\n function shareDuty() {\r\n $scope.submitted = true;\r\n \r\n duty.Comments = $scope.duty.Comments;\r\n\r\n BucketFactory.shareDuty(duty, function (responseData) {\r\n displayMessage(\"Duty shared.\",false);\r\n $timeout(function () {closeDuty(true);} , 5000);\r\n },\r\n function (){\r\n displayMessage(\"Failed to share duty.\",true);\r\n }\r\n );\r\n }\r\n\r\n /**\r\n * Displays message when share/unshare \r\n * @memberof BucketModalCtrl\r\n * @param {string} message \r\n * @param {boolean} hasErrors \r\n */\r\n function displayMessage(message, hasErrors) {\r\n $scope.responseText = message;\r\n $scope.responseHasErrors = hasErrors;\r\n }\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('proposal', proposal);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name proposal\r\n * @restrict E\r\n * @description\r\n * Implementation of proposal\r\n * Initialize the proposal element of bucket\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */ \r\nfunction proposal(BucketFactory, $uibModal,$filter) {\r\n function link(scope, element, attrs){\r\n scope.isOpen = false;\r\n scope.successful = false;\r\n scope.error = false;\r\n scope.proposal.createDisabled = false;\r\n \r\n scope.duty = scope.proposal.Duty;\r\n \r\n scope.loading = false;\r\n scope.errorMessage = null;\r\n \r\n scope.ProposedDuties = new Array();\r\n scope.RequestedDuties = new Array();\r\n scope.AllDuties = new Array();\r\n\r\n scope.fetch = fetchInformation;\r\n scope.viewInfoModal = viewInfoModal;\r\n scope.createProposal = createProposal;\r\n scope.evaluateProposal = evaluateProposal;\r\n scope.undoProposalStatus = undoProposalStatus;\r\n scope.acknowledgeProposal = acknowledgeProposal;\r\n scope.confirmCreateProposal = confirmCreateProposal;\r\n scope.getFirstInfoIcon = getFirstInfoIcon;\r\n scope.getSecondInfoIcon = getSecondInfoIcon;\r\n scope.hasSecondInfoIcon = hasSecondInfoIcon;\r\n scope.getTextColor = getTextColor;\r\n scope.getFirstActionIcon = getFirstActionIcon;\r\n scope.hasFirstActionIcon = hasFirstActionIcon;\r\n scope.getSecondActionIcon = getSecondActionIcon;\r\n scope.hasSecondActionIcon = hasSecondActionIcon;\r\n scope.getFetchIcon = getFetchIcon;\r\n scope.getInfoMessage = getInfoMessage;\r\n scope.firstAction = firstAction;\r\n scope.secondaryAction = secondaryAction;\r\n scope.showEndDate = showEndDate;\r\n scope.showTime = showTime;\r\n\r\n\r\n if(scope.duty.Comments && scope.duty.Comments != \"\"){\r\n scope.dutyCommentElipsis = dutyCommentElipsis(110);\r\n scope.showFullComment = false;\r\n }\r\n \r\n scope.toggleFullCommentVisibility = toggleFullCommentVisibility;\r\n\r\n /**\r\n * Toggles proposal comment\r\n * @memberof proposal\r\n */\r\n function toggleFullCommentVisibility(){\r\n scope.showFullComment = !scope.showFullComment;\r\n }\r\n\r\n /**\r\n * Shows only the first charNo characters of the comment\r\n * @memberof proposal\r\n * @param {number} charNo \r\n */\r\n function dutyCommentElipsis(charNo){\r\n var comments = scope.duty.Comments;\r\n if(scope.duty.Comments.length > charNo){\r\n comments = scope.duty.Comments.substring(0,charNo) + \"...\";\r\n }\r\n return comments;\r\n }\r\n\r\n /**\r\n * Updates proposal when a change occurs (create, evaluate or undo)\r\n * @memberof proposal\r\n * @param {object} newProp - The updated proposal \r\n */\r\n function updateProposal(newProp){\r\n if(newProp){\r\n scope.proposal.Status = newProp.Status;\r\n scope.proposal.State = newProp.State;\r\n scope.proposal.Id = newProp.Id;\r\n scope.proposal.isAcknowledged = newProp.isAcknowledged;\r\n } \r\n }\r\n \r\n /**\r\n * Fetches proposal info (Proposed and Requested duties alongside Crew and Route details for each one) \r\n * @memberof proposal\r\n */\r\n function fetchInformation(){\r\n if(!(scope.actionDisabled && scope.proposal.Status == 'Shared')){\r\n if(!(scope.proposal.AllDuties && scope.proposal.AllDuties.length>0)){\r\n scope.loading = true;\r\n if(scope.proposal.Status == \"Shared\" && !scope.actionDisabled){\r\n BucketFactory.fetchSharedProposal(scope.currentDutyId, scope.duty.Id, insertInformation )\r\n .catch(errorCall);\r\n }else{\r\n BucketFactory.fetchProposal(scope.proposal.Id, insertInformation)\r\n .catch(errorCall);\r\n }\r\n }else{\r\n scope.isOpen = !scope.isOpen; //collapse\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Handles error from fetchSharedProposal() and fetchProposal() \r\n * @memberof proposal\r\n */\r\n function errorCall(){\r\n scope.isOpen = false;\r\n scope.loading = false;\r\n displayMessage(\"Failed to fetch information.\", true);\r\n }\r\n\r\n /**\r\n * Callback for handling the successful response of fetchSharedProposal() and fetchProposal()\r\n * @memberof proposal\r\n * @param {object} data \r\n */\r\n function insertInformation(data){\r\n var success = data.data.success;\r\n var errorMessage = data.data.errorMessage;\r\n //always show duties even if success is false\r\n if(data.data.data.duty){\r\n var ProposedDuties = data.data.data.duty.ProposedDuties;\r\n var RequestedDuties = data.data.data.duty.RequestedDuties;\r\n scope.proposal.HasMultiDuties = data.data.data.duty.HasMultiDuties;\r\n\r\n ProposedDuties = $filter('orderBy')(ProposedDuties, 'DutyDate');\r\n RequestedDuties = $filter('orderBy')(RequestedDuties, 'DutyDate');\r\n \r\n if(ProposedDuties && RequestedDuties){\r\n scope.proposal.AllDuties = []; \r\n var tableMaxRowLength = (ProposedDuties.length > RequestedDuties.length) ? ProposedDuties.length : RequestedDuties.length;\r\n \r\n for(var i = 0; i < tableMaxRowLength; i++){\r\n \r\n if(scope.proposal.Status == \"Shared\" || scope.proposal.State == \"Out\"){\r\n var matchedDuty = {\r\n Proposed : ProposedDuties[i], //you give\r\n Requested : RequestedDuties[i] //you take\r\n };\r\n }\r\n else{ //scope.proposal.State == \"In\"\r\n var matchedDuty = {\r\n Proposed : RequestedDuties[i], //you give\r\n Requested : ProposedDuties[i] //you take\r\n };\r\n }\r\n \r\n scope.proposal.AllDuties.push(matchedDuty);\r\n } \r\n \r\n scope.proposal.ProposedDuties = ProposedDuties;\r\n scope.proposal.RequestedDuties = RequestedDuties;\r\n scope.isOpen = true; \r\n }\r\n }\r\n\r\n if(!success){\r\n //if not enough rest time\r\n //if no available combinations\r\n scope.proposal.createDisabled = true;\r\n }else{\r\n scope.proposal.createDisabled = false;\r\n }\r\n\r\n //always show errorMessage even if success is true\r\n if(errorMessage && errorMessage.length > 0){\r\n displayMessage(errorMessage, true);\r\n }\r\n else{\r\n scope.errorMessage = null;\r\n }\r\n \r\n\r\n scope.loading = false;\r\n }\r\n \r\n /**\r\n * Opens modal for a specific duty in the table - Shows route and crew info \r\n * @memberof proposal\r\n * @param {number} id \r\n */\r\n function viewInfoModal(id){\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgProposalInfo.html',\r\n controller: 'ProposalInfoModalCtr',\r\n size: 'lg',\r\n resolve: {\r\n ProposedDuties: function () { return scope.proposal.ProposedDuties; },\r\n RequestedDuties: function () { return scope.proposal.RequestedDuties; },\r\n Id: function () {return id; },\r\n Status: function () { return scope.proposal.Status; },\r\n State: function () { return scope.proposal.State; }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Creates/Sends proposal\r\n * @memberof proposal\r\n */\r\n function createProposal(){\r\n var proposedDutiesIdList = [];\r\n var requestedDutiesIdList = [];\r\n\r\n angular.forEach(scope.proposal.ProposedDuties,function(duty){\r\n proposedDutiesIdList.push(duty.Id);\r\n });\r\n\r\n angular.forEach(scope.proposal.RequestedDuties,function(duty){\r\n requestedDutiesIdList.push(duty.Id);\r\n });\r\n\r\n\r\n //request body\r\n var proposal = {\r\n 'proposedDutiesIdList' : proposedDutiesIdList,\r\n 'requestedDutiesIdList' : requestedDutiesIdList\r\n };\r\n\r\n scope.loading = true;\r\n\r\n BucketFactory.createProposal(proposal, function (responseData) {\r\n displayMessage(\"Proposal has been sent\", false);\r\n scope.loading = false;\r\n updateProposal(responseData.data.data);\r\n if(scope.proposal.HasMultiDuties){ \r\n scope.refresh(); //needed in order to hide other duty from same proposal\r\n }\r\n })\r\n .catch(function(){\r\n displayMessage(\"Failed to send proposal.\", true);\r\n scope.loading = false;\r\n });\r\n }\r\n\r\n /**\r\n * Approves/Rejects proposal\r\n * @memberof proposal\r\n * @param {boolean} isApproved\r\n */\r\n function evaluateProposal(isApproved){\r\n var proposal = {};\r\n proposal.Id = scope.proposal.Id;\r\n proposal.isApproved = isApproved;\r\n \r\n var onSuccessMessage, onFailureMessage;\r\n \r\n if(isApproved){\r\n proposal.Status = \"Approved\";\r\n var onSuccessMessage = \"Approved proposal.\";\r\n var onFailureMessage = \"Failed to approve proposal.\";\r\n }\r\n else{\r\n proposal.Status = \"Rejected\";\r\n var onSuccessMessage = \"Rejected proposal.\";\r\n var onFailureMessage = \"Failed to reject proposal.\";\r\n }\r\n \r\n scope.loading = true;\r\n BucketFactory.evaluateProposal(proposal).then(function (responseData) {\r\n var success = responseData.data.success;\r\n if(success){\r\n var newProp = responseData.data.data;\r\n updateProposal(newProp);\r\n if(isApproved){\r\n scope.refresh(); //needed in order to disable other proposals\r\n }\r\n displayMessage(onSuccessMessage,false);\r\n }else{\r\n displayMessage(onFailureMessage,true);\r\n }\r\n })\r\n .catch(function(){\r\n displayMessage(onFailureMessage,true);\r\n });\r\n\r\n scope.loading = false;\r\n }\r\n\r\n /**\r\n * Reverts proposal to previous status\r\n * @memberof proposal\r\n */\r\n function undoProposalStatus(){\r\n scope.loading = true;\r\n var proposal = {};\r\n proposal.Id = scope.proposal.Id;\r\n\r\n var onSuccessMessage, onFailureMessage;\r\n\r\n if((scope.proposal.Status == \"Approved\") ||\r\n (scope.proposal.Status == \"Rejected\" && scope.proposal.State=='In')){\r\n var onSuccessMessage = \"Proposal has been reset.\";\r\n var onFailureMessage = \"Failed to reset proposal.\";\r\n }else{ //(scope.proposal.Status == \"Pending\" && scope.proposal.State=='Out')\r\n var onSuccessMessage = \"Withdrew proposal.\";\r\n var onFailureMessage = \"Failed to withraw proposal.\";\r\n }\r\n\r\n \r\n BucketFactory.undoProposalStatus(proposal.Id).then(function (responseData) {\r\n var previousStatus = scope.proposal.Status;\r\n var HasMultiDuties = scope.proposal.HasMultiDuties;\r\n var newProp = responseData.data.data;\r\n displayMessage(onSuccessMessage, false);\r\n scope.loading = false;\r\n updateProposal(newProp);\r\n if(previousStatus == \"Approved\"){\r\n scope.refresh(); //needed in order to enable other proposals again \r\n }\r\n else if(previousStatus == \"Pending\" && HasMultiDuties){\r\n scope.refresh(); //needed in order to show other duties from same proposal \r\n }\r\n })\r\n .catch(function(){\r\n scope.loading = false;\r\n displayMessage(onFailureMessage,true);\r\n });\r\n\r\n }\r\n\r\n /**\r\n * Displays error or success message\r\n * @memberof proposal\r\n * @param {string} message \r\n * @param {boolean} hasErrors \r\n */\r\n function displayMessage(message, hasErrors){\r\n \r\n if(hasErrors){\r\n scope.errorMessage = message;\r\n }else{\r\n scope.errorMessage = null;\r\n }\r\n }\r\n \r\n /**\r\n * Makes proposal acknowledged \r\n * Available when status is 'RejectedBySTP' or status is 'Rejected' and state is 'Out'\r\n * @memberof proposal\r\n */\r\n function acknowledgeProposal(){\r\n scope.loading = true;\r\n var proposalId = scope.proposal.Id;\r\n var onFailureMessage = \"Failed to acknowledge proposal.\";\r\n \r\n BucketFactory.acknowledgeProposal(proposalId).then(function (responseData) {\r\n scope.proposal.isAcknowledged = true;\r\n scope.loading = false;\r\n })\r\n .catch(function(){\r\n scope.loading = false;\r\n displayMessage(onFailureMessage, true);\r\n });\r\n }\r\n \r\n /**\r\n * Changes proposal's first info icon depending on its state and status\r\n * @memberof proposal\r\n * @returns {string} - Icon name\r\n */\r\n function getFirstInfoIcon(){\r\n var icon = \"\"\r\n if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out' ){\r\n icon=\"fa-thumbs-up\";\r\n }else if(scope.proposal.Status == \"Rejected\"){\r\n icon=\"fa-thumbs-down\";\r\n }else if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In'){\r\n icon=\"fa-thumbs-o-up\";\r\n }else if ( scope.proposal.Status == \"Shared\"){\r\n icon=\"fa-bitbucket\";\r\n }else if(scope.proposal.Status == \"Approved\"){\r\n icon = \"fa fa-handshake-o\"\r\n }else if ( scope.proposal.Status == \"ApprovedBySTP\"){\r\n icon=\"fa-thumbs-up\";\r\n }else if(scope.proposal.Status == \"RejectedBySTP\"){\r\n icon=\"fa-thumbs-o-down\";\r\n }\r\n return icon;\r\n }\r\n\r\n /**\r\n * Changes proposal's second info icon depending on its state and status\r\n * @memberof proposal\r\n * @returns {string} - Icon name\r\n */\r\n function getSecondInfoIcon(){\r\n var icon = \"\"\r\n if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out' ){\r\n icon=\"fa-clock-o text-gray\";\r\n }else if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In'){\r\n icon=\"fa-question-circle-o\";\r\n }\r\n return icon;\r\n } \r\n\r\n /**\r\n * Determines second info icon's visibility\r\n * @memberof proposal\r\n * @returns {boolean}\r\n */\r\n function hasSecondInfoIcon(){\r\n return (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In' ) ||(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out'); \r\n }\r\n\r\n /**\r\n * Changes column color depending on proposal's state and status\r\n * @memberof proposal\r\n * @returns {string} - Color's class\r\n */\r\n function getTextColor(){\r\n var textclass=\"\";\r\n if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out' ){\r\n textclass=\"text-light-blue\";\r\n }else if(scope.proposal.Status == \"Rejected\"){\r\n textclass=\"text-red\";\r\n }else if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In'){\r\n textclass=\"text-orange\";\r\n }else if(scope.proposal.Status == \"Approved\" ){\r\n textclass=\"text-green\";\r\n }else if ( scope.proposal.Status == \"Shared\"){\r\n textclass=\"text-blue-gray\";\r\n }else if ( scope.proposal.Status == \"ApprovedBySTP\"){\r\n textclass=\"text-green\";\r\n }else if(scope.proposal.Status == \"RejectedBySTP\"){\r\n textclass=\"text-red\";\r\n }\r\n return textclass;\r\n }\r\n\r\n /**\r\n * Changes proposal's first action icon depending on its state and status\r\n * @memberof proposal\r\n * @returns {string} - Icon name\r\n */\r\n function getFirstActionIcon(){\r\n var icon = \"\"\r\n if(scope.proposal.createDisabled){\r\n icon = \"fa-ban text-red\"; //no action permitted\r\n }else if((scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out' )\r\n || scope.proposal.Status == \"Approved\" ){\r\n icon=\" fa-times text-gray \"; //undo\r\n }else if(scope.proposal.Status == \"Rejected\" && scope.proposal.State == \"In\"){\r\n icon=\" fa-times text-gray \"; //undo\r\n }else if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In' && !scope.actionDisabled){\r\n icon=\"fa-thumbs-o-up text-green\"; //approve\r\n }else if ( scope.proposal.Status == \"Shared\" && !scope.actionDisabled){\r\n icon=\"fa-thumbs-o-up text-light-blue\"; //create\r\n }\r\n \r\n return icon;\r\n }\r\n \r\n /**\r\n * Changes proposal's fetch icon if create action is disabled \r\n * @memberof proposal\r\n * @returns {string} - Icon name\r\n */\r\n function getFetchIcon(){\r\n var icon = \"\";\r\n if(scope.proposal.createDisabled){\r\n icon = \"fa-ban text-red\";\r\n }\r\n else{\r\n icon = \"fa-search\";\r\n }\r\n return icon;\r\n }\r\n\r\n /**\r\n * Changes proposal's second action icon depending on its state and status\r\n * @memberof proposal\r\n * @returns {string} - Icon name\r\n */\r\n function getSecondActionIcon(){\r\n var icon = \"\"\r\n if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In'){\r\n icon=\"fa-thumbs-o-down text-red\"; //reject\r\n }\r\n return icon;\r\n\r\n } \r\n \r\n /**\r\n * Determines first action icon's visibility\r\n * @memberof proposal\r\n * @returns {boolean}\r\n */\r\n function hasFirstActionIcon(){\r\n return !( scope.proposal.Status == \"ApprovedBySTP\" || scope.proposal.Status == \"RejectedBySTP\") ;\r\n }\r\n \r\n /**\r\n * Determines second action icon's visibility\r\n * @memberof proposal\r\n * @returns {boolean}\r\n */\r\n function hasSecondActionIcon(){\r\n return (scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In') || ( scope.proposal.Status == \"Shared\");\r\n }\r\n \r\n /**\r\n * Returns info message depending on proposal's state and status\r\n * @memberof proposal\r\n * @returns {string} - Message\r\n */\r\n function getInfoMessage(){\r\n var text=\"\";\r\n if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out' ){\r\n text=\"your proposal is pending\";\r\n }else if(scope.proposal.Status == \"Rejected\" && scope.proposal.State == 'Out'){\r\n text=\"your proposal has been rejected\";\r\n }\r\n else if(scope.proposal.Status == \"Rejected\" && scope.proposal.State == 'In'){\r\n text=\"you have rejected the proposal\";\r\n }else if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In'){\r\n text=\"your response is pending\";\r\n }else if(scope.proposal.Status == \"Approved\" && scope.proposal.State == 'In' ){\r\n text=\"you have accepted the proposal. Your request is sent for approval\";\r\n }else if(scope.proposal.Status == \"Approved\" && scope.proposal.State == 'Out' ){\r\n text=\"your proposal has been accepted! Your request is sent for approval\";\r\n }else if ( scope.proposal.Status == \"ApprovedBySTP\"){\r\n text=\"your request has been approved!\";\r\n }else if(scope.proposal.Status == \"RejectedBySTP\"){\r\n text=\"your request has been rejected by STP\";\r\n }\r\n \r\n return text;\r\n }\r\n\r\n /**\r\n * Determines duty's endDate visibility\r\n * @memberof proposal\r\n * @returns {boolean}\r\n */\r\n function showEndDate(duty){\r\n var show = false;\r\n var diffMin = Date.DifferenceInMinutes(duty.DutyBegin, duty.DutyEnd);\r\n var diffHours = diffMin / 60;\r\n if(diffHours >= 24){ //endDate will show if duty exceeds 24 hours\r\n show = true;\r\n }\r\n return show;\r\n }\r\n\r\n /**\r\n * Hides duty begin and end time if needed\r\n * @param {object} duty \r\n */\r\n function showTime(duty){\r\n var show = true;\r\n var diffMin = Date.DifferenceInMinutes(duty.DutyBegin, duty.DutyEnd);\r\n if(!diffMin){ //Time will not show if duty lasts all day (ex. Day Off: 00:00 - 00:00)\r\n show = false;\r\n }\r\n return show;\r\n }\r\n\r\n /**\r\n * Chooses first icon's action depending on proposal's state and status\r\n * @memberof proposal\r\n */\r\n function firstAction(){\r\n if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'Out' ){\r\n undoProposalStatus();\r\n }else if(scope.proposal.Status == \"Approved\" ){\r\n confirmUndoApproved();\r\n }else if(scope.proposal.Status == \"Rejected\" && scope.proposal.State == 'In'){\r\n undoProposalStatus();\r\n }else if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In'){\r\n evaluateProposal(true); //approve\r\n }else if( scope.proposal.Status == \"Shared\" && !scope.proposal.createDisabled){\r\n if(scope.errorMessage && scope.errorMessage.length > 0){\r\n confirmCreateProposal(); //fetch success with errorMessage\r\n }\r\n else{\r\n createProposal();\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Chooses second icon's action depending on proposal's state and status\r\n * @memberof proposal\r\n */\r\n function secondaryAction(){\r\n if(scope.proposal.Status == \"Pending\" && scope.proposal.State == 'In'){\r\n evaluateProposal(false); // reject proposal\r\n }\r\n }\r\n\r\n /**\r\n * Opens confirmation modal when undo is requested on an approved proposal\r\n * @memberof proposal\r\n */\r\n function confirmUndoApproved() {\r\n bootbox.dialog({\r\n message: \"You are about to cancel your accepted proposal.

\",\r\n title: \"Caution!\",\r\n buttons: {\r\n confirm:{\r\n label: 'Confirm',\r\n className: \"btn-danger\",\r\n callback: function(){\r\n undoProposalStatus();\r\n }\r\n }, \r\n cancel:{\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function(){}\r\n }\r\n }\r\n })\r\n }\r\n \r\n /**\r\n * Opens confirmation modal when create is requested on an alternate proposal\r\n * @memberof proposal\r\n */\r\n function confirmCreateProposal() {\r\n bootbox.dialog({\r\n message: \"Would you like to proceed with the alternate proposal?

\",\r\n title: \"Send request\",\r\n buttons: {\r\n confirm:{\r\n label: 'Confirm',\r\n className: \"btn-success\",\r\n callback: function(){\r\n createProposal();\r\n }\r\n }, \r\n cancel:{\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function(){}\r\n }\r\n }\r\n })\r\n } \r\n\r\n }\r\n \r\n return {\r\n\t\t\trestrict: 'E',\r\n\t\t\tterminal: true,\r\n templateUrl: 'views/bucket/proposal.tpl.html',\r\n\t\t\tscope : {\r\n proposal: '=',\r\n displayMessage : '&onDisplay',\r\n refresh : '&onRefresh',\r\n actionDisabled: '=',\r\n currentDutyDate: '=',\r\n currentDutyId : '=',\r\n sharedCount : '='\r\n },\r\n link: link\r\n }\r\n}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('ProposalInfoModalCtr', ProposalInfoModalCtr)\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ProposalInfoModalCtr\r\n * @description \r\n * Shows duty crew and route info\r\n * @ngInject\r\n */\r\n\r\n function ProposalInfoModalCtr($scope, $uibModalInstance, ProposedDuties, RequestedDuties, Id, Status, State){\r\n $scope.RequestedDuties = RequestedDuties;\r\n $scope.ProposedDuties = ProposedDuties;\r\n\r\n $scope.cancel = cancel; \r\n $scope.next = next;\r\n $scope.previous = previous;\r\n\r\n var allDuties = [];\r\n\r\n //\"You give\" items are put first in list\r\n if(Status == \"Shared\" || State == \"Out\"){\r\n allDuties = ProposedDuties.concat(RequestedDuties);\r\n }\r\n else{ //State == \"In\"\r\n allDuties = RequestedDuties.concat(ProposedDuties);\r\n }\r\n \r\n for(var i = 0; i < allDuties.length; i++){\r\n if(allDuties[i].Id == Id){\r\n $scope.currentPage = i+1;\r\n break;\r\n }\r\n }\r\n\r\n $scope.allDuties = allDuties;\r\n \r\n /**\r\n * Moves to next duty\r\n * @memberof ProposalInfoModalCtr\r\n */\r\n function next(){\r\n if($scope.currentPage != allDuties.length)\r\n $scope.currentPage++;\r\n }\r\n\r\n /**\r\n * Moves to previous duty\r\n * @memberof ProposalInfoModalCtr\r\n */\r\n function previous(){\r\n if($scope.currentPage != 1)\r\n $scope.currentPage--;\r\n }\r\n\r\n /**\r\n * Closes modal\r\n * @memberof ProposalInfoModalCtr\r\n */\r\n function cancel() {\r\n $uibModalInstance.close('cancel');\r\n }\r\n }\r\n})();\r\n","(function() {\r\n 'use strict';\r\na3_cabin_reports.controller('AssessmentCtrl',AssessmentCtrl);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name AssessmentCtrl\r\n * @description \r\n * Manages the Cabin Crew Feedback View \r\n * @ngInject\r\n */\r\nfunction AssessmentCtrl($scope, $location, CrewAssessmentFactory, $routeParams, SettingsMain, orderByFilter, FlightFactory,$timeout) {\r\n\r\n\t\tvar editingPage = SettingsMain.getEditingPage();\r\n\t\tvar flightId = $routeParams.flightId;\r\n\t\tvar minDate,maxDate,flightRouteString;\r\n \r\n SettingsMain.setEditingPage(\"assessment\");\r\n\t\tvar text = \"\";\r\n\r\n\t\tif (flightId == \"temp\") {\r\n\t\t\tvar crewAssessment = CrewAssessmentFactory.getTempAssessment();\r\n \r\n $scope.flight = FlightFactory.getFlightFromStorage(crewAssessment.FlightId);\r\n SettingsMain.setEditingPage(null);\r\n\t\t} else {\r\n $scope.flight = FlightFactory.getFlightFromStorage(flightId);\r\n\t\t\tvar crewAssessment = CrewAssessmentFactory.getCrewAssessmentFromStorage( $scope.flight.assessment.Id);\r\n\t\t}\r\n \r\n if (crewAssessment){\r\n \r\n \r\n var flights = orderByFilter(crewAssessment.Flights, orderByDate, false);\r\n\r\n for (var i = 0; i < flights.length; i++) {\r\n if (i==0){\r\n minDate = flights[i].ScheduledDepartureDateUTC + \"T\" + flights[i].ScheduledDepartureTimeUTC ;\r\n flightRouteString = flights[i].Departure\r\n }else if ( i == (flights.length-1)){\r\n maxDate = flights[i].ScheduledArrival;\r\n flightRouteString = flightRouteString + \"-\" +flights[i].Departure + \"-\" + flights[i].Arrival;\r\n }else{\r\n flightRouteString = flightRouteString + \"-\" +flights[i].Departure ;\r\n }\r\n }\r\n\r\n var route = {\r\n Route : crewAssessment.Route,\r\n DutyDate : crewAssessment.DutyDate,\r\n MinDate : minDate,\r\n MaxDate : maxDate,\r\n FlightRoute : flightRouteString\r\n }\r\n\r\n for (var i = 0; i < crewAssessment.assessedBy.length; i++) {\r\n if (i > 0) {\r\n var assessed = ', ' + crewAssessment.assesedBy[i].Name;\r\n } else {\r\n var assessed = crewAssessment.assessedBy[i].Name;\r\n }\r\n text = text.concat(assessed);\r\n }\r\n\r\n $scope.isFirstOpen = true;\r\n $scope.assessment = crewAssessment;\r\n $scope.togglePanel = togglePanel;\r\n $scope.route = route;\r\n $scope.assessedBy = text;\r\n }\r\n\r\n\t\t$scope.clearRemarks = clearRemarks;\r\n\t\t$scope.avgValue = avgValue;\r\n\t\t$scope.updateValues = updateValues;\r\n\t\t$scope.IsCompleted = IsCompleted;\r\n $scope.IsSynched = IsSynched;\r\n\t\t$scope.assessments_not_completed = CrewAssessmentFactory.getCountOfUncompletedAssessments();\r\n\t\t$scope.saveClicked = saveClicked;\r\n\t\t$scope.saveDraftClicked = saveDraftClicked;\r\n\t\t$scope.assesmentCSSClass = assesmentCSSClass;\r\n\t\t$scope.assesmentIconClass = assesmentIconClass;\r\n\t\t$scope.isPanelOpen = false;\r\n $scope.discard = discard;\r\n \r\n $scope.infosaveaction = false;\r\n\r\n\t\t\r\n /**\r\n * Display a successful save message according to the save status \r\n * @memberof AssessmentCtrl\r\n * @param {string} state the state of the selected Cabin Crew Feedback\r\n */\r\n function infoSaveOperation(state){\r\n\t\t\t\tif(state=='Completed'){\r\n\t\t\t\t\t\t$scope.infosaveactiontype = state;\r\n\t\t\t\t\t\t$scope.infosaveaction = true;\r\n\t\t\t\t}else if(state=='Draft'){\r\n\t\t\t\t\t\t$scope.infosaveactiontype = state;\r\n\t\t\t\t\t\t$scope.infosaveaction = true\r\n\t\t\t\t}else if(state=='discard'){\r\n\t\t\t\t\t\t$scope.infosaveactiontype = state;\r\n\t\t\t\t\t\t$scope.infosaveaction = true\r\n\t\t\t\t}\r\n\t\t\t\t\r\n\t\t\t\t$timeout(function(){\r\n\t\t\t\t\t\t $scope.infosaveaction = false;\r\n\t\t\t\t},5000);\r\n\t\t\t\t\r\n\t\t}\r\n\r\n /**\r\n * Convers date string to JS object\r\n * @memberof AssessmentCtrl\r\n * @param {string} ScheduledArrival The string date of ScheduledArrival \r\n * @returns {Object} ScheduledArrival\r\n */\r\n\t\tfunction orderByDate(item) {\r\n\t\t\tvar date = new Date(item.ScheduledArrival);\r\n\t\t\treturn date;\r\n\t\t}\r\n\r\n /**\r\n * Clear Remarks\r\n * @memberof AssessmentCtrl\r\n * @param {string} item The Crew assessment Template question item \r\n */\r\n\t\tfunction clearRemarks(item) {\r\n\t\t\t// put preset comments\r\n\t\t\tif (item != null && item.ItemDescr) {\r\n\t\t\t\titem.ItemDescr = null;\r\n\t\t\t}\r\n \r\n if (item != null && item.Review) {\r\n\t\t\t\titem.Review = null;\r\n\t\t\t}\r\n\t\t}\r\n\t\r\n /**\r\n * Returns the avarage score of the questions.\r\n * @memberof AssessmentCtrl\r\n * @param {array} items The Crew assessment Template question items \r\n * @returns {number} retval\r\n */\r\n\t\tfunction avgValue(items) {\r\n\t\t\tvar sum = 0;\r\n\t\t\tif (!items || items.length == 0) {\r\n\t\t\t\treturn sum;\r\n\t\t\t}\r\n\t\t\tfor (var i = 0; i < items.length; i++) {\r\n\t\t\t\tif (items[i]) {\r\n\t\t\t\t\tsum = sum + parseInt(items[i].ItemValue);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tvar retval = (sum / items.length) ? (sum / items.length).toFixed(1) : '-';\r\n\t\t\treturn retval;\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Updates the value for the selected crewmember for this Cabin Crew Feedback and update the temporary Cabin Crew Feedback\r\n * @memberof AssessmentCtrl \r\n * @param {object} crewMember The Crew member\r\n * @param {object} assessment The Crew assessment \r\n */\r\n\t\tfunction updateValues(crewMember, assessment) {\r\n\r\n crewMember.IsCompleted = crewMember.Review != null && crewMember.Review.trim().length>0;\r\n\r\n\t\t\tCrewAssessmentFactory.saveTempAssessment(assessment,$scope.flight.FlightId)\r\n\t\t}\r\n\t\t\t\r\n \r\n /**\r\n * Evaluate if this Cabin Crew Feedback is valid and ready to send\r\n * @memberof AssessmentCtrl \r\n * @param {object} assessment The Crew assessment \r\n * @returns {boolean} isCompleted\r\n */\r\n\t\tfunction IsCompleted(crewAssessment) {\r\n\t\t\tvar isCompleted = true;\r\n\t\t\tfor (var j = 0; j < crewAssessment.CrewAssessmentMembers.length; j++) {\r\n\t\t\t\tif (!(crewAssessment.CrewAssessmentMembers[j].Review != null && crewAssessment.CrewAssessmentMembers[j].Review.trim().length>0)) {\r\n\t\t\t\t\tif(!crewAssessment.CrewAssessmentMembers[j].IsExist && (crewAssessment.CrewAssessmentMembers[j].IsValid || crewAssessment.CrewAssessmentMembers[j].IsOverride)){\r\n isCompleted = false; \r\n }\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn isCompleted;\r\n\t\t}\r\n /**\r\n * Evaluate if this Cabin Crew Feedback is synched\r\n * @memberof AssessmentCtrl \r\n * @param {object} assessment The Crew assessment \r\n * @returns {boolean} IsSynched\r\n */\r\n function IsSynched () {\r\n var IsSynched = false;\r\n if(crewAssessment.Status == \"Stored\"){\r\n IsSynched = true;\r\n }\r\n return IsSynched;\r\n }\r\n\t\t\t\r\n\r\n /**\r\n * Save the Cabin Crew Feedback\r\n * @memberof AssessmentCtrl \r\n * @param {object} assessment The Cabin Crew Feedback\r\n */\r\n\t\tfunction saveAssessment(assessment) {\r\n\t\t\tCrewAssessmentFactory.setCrewAssessmentToStorage(assessment);\r\n\t\t\tCrewAssessmentFactory.updateFlightsAssessment(assessment);\r\n CrewAssessmentFactory.updateCrewRouteAssessment(assessment);\r\n\t\t}\r\n\t \r\n /**\r\n * Save the Cabin Crew Feedback As Completed\r\n * @memberof AssessmentCtrl \r\n * @param {object} assessment The Cabin Crew Feedback\r\n */\r\n\t\tfunction saveClicked(assessment) {\r\n\t\t\tassessment.Status = 'Completed'\r\n\t\t\tsaveAssessment(assessment);\r\n infoSaveOperation(assessment.Status);\r\n\t\t\tSettingsMain.setEditingPage(null);\r\n\t\t\tCrewAssessmentFactory.clearTempAssessment();\r\n $location.path('/flightinfo/'+ $scope.flight.FlightId);\r\n\t\t}\r\n \r\n /**\r\n * Discard all the changes on the cabin crew feedback that are not saved\r\n * @memberof AssessmentCtrl \r\n */\r\n function discard(){\r\n SettingsMain.setEditingPage(null);\r\n $scope.assessment = CrewAssessmentFactory.getCrewAssessmentFromStorage( $scope.flight.assessment.Id);\r\n infoSaveOperation('discard');\r\n }\r\n\r\n /**\r\n * Save the Cabin Crew Feedback As Draft\r\n * @memberof AssessmentCtrl \r\n * @param {object} assessment The Cabin Crew Feedback\r\n */\r\n\t\tfunction saveDraftClicked(assessment) {\r\n\r\n\t\t\tassessment.Status = 'Draft'\r\n\t\t\tsaveAssessment(assessment);\r\n infoSaveOperation(assessment.Status);\r\n\t\t\tSettingsMain.setEditingPage(null);\r\n\t\t\tCrewAssessmentFactory.clearTempAssessment();\r\n\t\t}\r\n\t\r\n\r\n /**\r\n * Open and close the selected Panel\r\n * @memberof AssessmentCtrl \r\n * @param {number} panelId The panel's Id\r\n */\r\n\t\tfunction togglePanel(panelId) {\r\n\t\t\t$('#' + panelId).toggle();\r\n\t\t\tif (panelId == \"info-panel\")\r\n\t\t\t\t$scope.isPanelOpen = !$scope.isPanelOpen;\r\n\t\t}\r\n\t\t\r\n /**\r\n * The css class for the selected crew member\r\n * @memberof AssessmentCtrl \r\n * @param {Object} crewMember The assessed crew member\r\n * @returns {string} cssClass\r\n */\r\n\t\tfunction assesmentCSSClass(crewMember){\r\n\t\t\tif(!crewMember.IsExist && crewMember.IsCompleted && (crewMember.IsValid || crewMember.IsOverride)){\r\n\t\t\t\treturn 'panel-blue';\r\n\t\t\t}else if(!crewMember.IsExist && !crewMember.IsCompleted && (crewMember.IsValid || crewMember.IsOverride) ){\r\n\t\t\t\treturn 'panel-orange';\r\n\t\t\t}else if(!crewMember.IsExist && !crewMember.IsValid && !crewMember.IsOverride ){\r\n\t\t\t\treturn 'panel-default';\r\n\t\t\t}else if(crewMember.IsExist){\r\n\t\t\t\treturn 'panel-green';\r\n\t\t\t} \r\n\t\t}\r\n\t\t\t\r\n /**\r\n * The icon for the selected crew member\r\n * @memberof AssessmentCtrl \r\n * @param {Object} crewMember The assessed crew member\r\n * @returns {string} iconClass\r\n */\r\n\t\tfunction assesmentIconClass(crewMember){\r\n\t\t\tif(!crewMember.IsExist && crewMember.IsCompleted && (crewMember.IsValid || crewMember.IsOverride)){\r\n\t\t\t\treturn 'fa fa-check';\r\n\t\t\t}else if(!crewMember.IsExist && !crewMember.IsCompleted && (crewMember.IsValid || crewMember.IsOverride) ){\r\n\t\t\t\treturn 'fa fa-pencil';\r\n\t\t\t}else if(!crewMember.IsExist && !crewMember.IsValid && !crewMember.IsOverride ){\r\n\t\t\t\treturn 'fa fa-times';\r\n\t\t\t}else if(crewMember.IsExist){\r\n\t\t\t\treturn 'fa fa-floppy-o';\r\n\t\t\t} \r\n\t\t}\r\n\r\n\t}\r\n \r\n})();","(function() {\r\n 'use strict';\r\na3_cabin_reports.factory('AssessmentSyncResultFactory', AssessmentSyncResultFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AssessmentSyncResultFactory\r\n * @description \r\n * Add, Update, Delete and Get Cabin Crew Feedback Sync Results.\r\n * @ngInject\r\n */\r\nfunction AssessmentSyncResultFactory(GenericService) {\r\n\r\n /**\r\n * Initialize the CrewAssessment\r\n * @memberof AssessmentSyncResultFactory\r\n */\r\n\t\tfunction AssessmentSyncResult() {\r\n\t\t\tthis.Route = null;\r\n\t\t\tthis.DutyDate = null;\r\n\t\t\tthis.message = null;\r\n\t\t\tthis.success = null;\r\n\t\t}\r\n\r\n\t\tvar objType = 'assessmentSyncResults';\r\n\t\tvar objCallback = AssessmentSyncResult; \r\n\t\t\r\n\t\tvar service = {\r\n\t\t\tgetAssessmentSyncResultsFromStorage: getAssessmentSyncResultsFromStorage,\r\n\t\t\tsetAssessmentSyncResultsToStorage : setAssessmentSyncResultsToStorage,\r\n\t\t\tgetSuccesses : getSuccesses,\r\n\t\t\tgetFailures : getFailures\r\n\t\t}\r\n\r\n /**\r\n * Get Assessment Sync Results\r\n * @memberof AssessmentSyncResultFactory\r\n * @returns {Array} AssessmentSyncResults \r\n */\r\n\t\tfunction getAssessmentSyncResultsFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save Assessment Sync Results in Local Storage\r\n * @memberof AssessmentSyncResultFactory\r\n * @param {Array} AssessmentSyncResults A list of Assessment Sync Results\r\n */\r\n\t\tfunction setAssessmentSyncResultsToStorage(assessmentSyncResults) {\r\n\t\t\tGenericService.saveAll(assessmentSyncResults,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get Successfull Assessment Sync Results from Local Storage\r\n * @memberof AssessmentSyncResultFactory\r\n * @param {Array} AssessmentSyncResults A list of Assessment Sync Results\r\n * @returns {Array} AssessmentSyncResults \r\n */\r\n\t\tfunction getSuccesses(syncResults) {\r\n\t\t\tvar result = 0;\r\n\t\t\tif (!syncResults) {\r\n\t\t\t\treturn result;\r\n\t\t\t}\r\n\t\t\tfor (var i = 0; i < syncResults.length; i++) {\r\n\t\t\t\tif (syncResults[i].success == true) {\r\n\t\t\t\t\tresult = result + 1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n \r\n /**\r\n * Get Failed Assessment Sync Results from Local Storage\r\n * @memberof AssessmentSyncResultFactory\r\n * @param {Array} AssessmentSyncResults A list of Assessment Sync Results\r\n * @returns {Array} AssessmentSyncResults \r\n */\r\n\t\tfunction getFailures(syncResults) {\r\n\t\t\tvar result = 0;\r\n\t\t\tif (!syncResults) {\r\n\t\t\t\treturn result;\r\n\t\t\t}\r\n\t\t\tfor (var i = 0; i < syncResults.length; i++) {\r\n\t\t\t\tif (syncResults[i].success == false) {\r\n\t\t\t\t\tresult = result + 1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n \r\n})();","(function() {\r\n 'use strict';\r\na3_cabin_reports.factory('CrewAssessmentFactory', CrewAssessmentFactory);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewAssessmentFactory\r\n * @description \r\n * Add, Update, Delete and Get Cabin Crew Feedback.\r\n * @ngInject\r\n */\r\nfunction CrewAssessmentFactory(localStorageMD5Service, CrewAssessmentMemberFactory, FlightFactory, CrewAssessmentTemplateFactory, CabinReportLocalEditFactory,GenericService, CrewRouteFactory) {\r\n\r\n /**\r\n * Initialize the CrewAssessment\r\n * @memberof CrewAssessmentFactory\r\n */\r\n\t\tfunction CrewAssessment() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.UserId = null;\r\n\t\t\tthis.Route = null;\r\n\t\t\tthis.DutyDate = null;\r\n\t\t\tthis.DutyDay = null;\r\n\t\t\tthis.AcType = null;\r\n\t\t\tthis.Status = 'Pending';\r\n\t\t\tthis.IsExist = false;\r\n\t\t\tthis.assessedBy = [];\r\n\t\t\tthis.CrewAssessmentMembers = [];\r\n\t\t\tthis.Flights = [];\r\n\t\t\tthis.GetId = GetId;\r\n this.start = null;\r\n this.end = null;\r\n\t\t}\r\n\t\t\t\t\r\n\t\tvar objType = 'crewAssessments';\r\n\t\tvar objCallback = CrewAssessment; \r\n\t\t\t\t\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tgetCrewAssessmentsFromStorage : getCrewAssessmentsFromStorage,\r\n\t\t\tsetCrewAssessmentsToStorage : setCrewAssessmentsToStorage,\r\n\t\t\tsetCrewAssessmentToStorage : setCrewAssessmentToStorage,\r\n\t\t\tgetCrewAssessmentFromStorage : getCrewAssessmentFromStorage,\r\n\t\t\tgetCountOfUncompletedAssessments : getCountOfUncompletedAssessments,\r\n\t\t\tgetCrewAssessmentByRoute : getCrewAssessmentByRoute,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tgetNewCrewAssessment : getNewCrewAssessment,\r\n\t\t\tgetTempAssessment : getTempAssessment,\r\n\t\t\tsaveTempAssessment : saveTempAssessment,\r\n\t\t\tclearTempAssessment : clearTempAssessment,\r\n\t\t\tupdateCrewMembers : updateCrewMembers,\r\n\t\t\tupdateCrewAssessment : updateCrewAssessment,\r\n\t\t\tgetAssesedCabinReports : getAssesedCabinReports,\r\n\t\t\texistsForRouteDutyDate : existsForRouteDutyDate,\r\n\t\t\tgetAssementsReadyToSend : getAssementsReadyToSend,\r\n\t\t\tstoreFlightsWithAssessments : storeFlightsWithAssessments,\r\n\t\t\tupdateFlightsAssessment : updateFlightsAssessment,\r\n updateAssessmentFlights : updateAssessmentFlights,\r\n\t\t\tstoreCrewRoutesWithAssessments : storeCrewRoutesWithAssessments,\r\n\t\t\tupdateCrewRouteAssessment : updateCrewRouteAssessment\r\n\t\t};\r\n\t\t\r\n\t\t//object functions\r\n /**\r\n * Overide default get Id\r\n * @memberof CrewAssessmentFactory\r\n * @returns {number} Id \r\n */\r\n\t\tfunction GetId(){\r\n\t\t\treturn this.Id;\r\n\t\t}\r\n\r\n\t\t//factory functions\r\n /**\r\n * Get Crew Assessments\r\n * @memberof CrewAssessmentFactory\r\n * @returns {Array} crewAssesments \r\n */\r\n\t\tfunction getCrewAssessmentsFromStorage() {\r\n var lsItems = GenericService.list(objType,objCallback);\r\n var items = [];\r\n for (var i = 0; i < lsItems.length; i++) {\r\n\t\t\t\tif (lsItems[i]) {\r\n\t\t\t\t\titems.push(lsItems[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn items;\r\n\t\t}\r\n\r\n /**\r\n * Save Crew Assessments to storage\r\n * @memberof CrewAssessmentFactory\r\n * @param {Array} crewAssessments A list of Cabin Crew Feedbacks\r\n */\r\n\t\tfunction setCrewAssessmentsToStorage(crewAssessments) {\r\n\t\t\tGenericService.saveAll(crewAssessments,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save one Crew Assessment to storage\r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} crewAssessment A Cabin Crew Feedback\r\n */\r\n\t\tfunction setCrewAssessmentToStorage(crewAssessment) {\r\n\t\t\tGenericService.save(crewAssessment,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get a Crew Assessment from storage\r\n * @memberof CrewAssessmentFactory\r\n * @param {number} crewAssessmentId the Id of the selected Crew Assessment\r\n * @returns {Object} crewAssesment\r\n */\r\n\t\tfunction getCrewAssessmentFromStorage(crewAssessmentId) {\r\n\t\t\treturn GenericService.get(crewAssessmentId,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get Count of Uncompleted Assessments \r\n * @memberof CrewAssessmentFactory\r\n * @returns {number} count\r\n */\r\n\t\tfunction getCountOfUncompletedAssessments() {\r\n\t\t\tvar crewAssessments = getCrewAssessmentsFromStorage();\r\n\t\t\tvar count = 0;\r\n\t\t\tif (crewAssessments == null)\r\n\t\t\t\treturn 0;\r\n\r\n\t\t\tfor (var i = 0; i < crewAssessments.length; i++) {\r\n\t\t\t\tif (!crewAssessments[i].IsExist && crewAssessments[i].Status != \"Completed\") {\r\n\t\t\t\t\tcount++;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn count;\r\n\t\t};\r\n\r\n /**\r\n * Get Crew Assessment By route and Duty Date\r\n * @memberof CrewAssessmentFactory\r\n * @param {string} Route the Route of the desired Crew Assessment\r\n * @param {string} DutyDate the Duty Date of the desired Crew Assessment\r\n * @returns {Object} crewAssesment\r\n */\r\n\t\tfunction getCrewAssessmentByRoute(Route, DutyDate) {\r\n\t\t\tvar crewAssessments = getCrewAssessmentsFromStorage();\r\n\t\t\tif (crewAssessments == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\tvar result = null;\r\n\r\n\t\t\tvar arrayLength = crewAssessments.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (crewAssessments[i].Route == Route && crewAssessments[i].DutyDate == DutyDate) {\r\n\t\t\t\t\tresult = crewAssessments[i];\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Extend Object from the default CrewAssessment Object\r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} obj a crewAssesment\r\n * @returns {Object} crewAssesment\r\n */\r\n\t\tfunction fromObject (obj){\r\n\t\t\treturn GenericService.fromObject(obj,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Extend an array of Objects from the default CrewAssessment Object\r\n * @memberof CrewAssessmentFactory\r\n * @param {Array} objList an Array Of crewAssesments\r\n * @returns {Array} crewAssesments\r\n */\r\n\t\tfunction fromObjectList (objList){\r\n\t\t\treturn GenericService.fromObjectList(objList,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Initialize a new Crew Assessment from the default Constructor\r\n * @memberof CrewAssessmentFactory\r\n * @returns {Object} crewAssesment\r\n */\r\n\t\tfunction getNewCrewAssessment() {\r\n\t\t\treturn GenericService.constructor(objCallback);\r\n\t\t};\r\n\r\n \r\n /**\r\n * Get the Temporary Assessment from the local storage\r\n * @memberof CrewAssessmentFactory\r\n * @returns {Object} crewAssesment\r\n */\r\n\t\tfunction getTempAssessment() {\r\n\t\t\tvar crewAssessmentLocalEdit = localStorageMD5Service.get('crewAssessmentLocalEdit_TEMP');\r\n\t\t\treturn fromObject(crewAssessmentLocalEdit);\r\n\t\t};\r\n\r\n /**\r\n * Save the Temporary Assessment to the local storage\r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} assessment a crewAssesment\r\n * @param {number} FlightId a crewAssesment\r\n */\r\n\t\tfunction saveTempAssessment(assessment,FlightId) {\r\n if (assessment){\r\n assessment.FlightId = FlightId;\r\n localStorageMD5Service.remove('crewAssessmentLocalEdit_TEMP');\r\n localStorageMD5Service.set('crewAssessmentLocalEdit_TEMP', assessment);\r\n }\r\n\t\t};\r\n\r\n /**\r\n * Remove the Temporary Assessment of the local storage\r\n * @memberof CrewAssessmentFactory\r\n */\r\n\t\tfunction clearTempAssessment() {\r\n\t\t\tlocalStorageMD5Service.remove('crewAssessmentLocalEdit_TEMP');\r\n\t\t};\r\n\r\n /**\r\n * Update CrewMembers of the assessment based on CCMSPositions\r\n * @memberof CrewAssessmentFactory\r\n * @param {string} CCMSPositions the ccms Position of the Flight\r\n * @param {string} Route The route of the assessment\r\n * @param {string} DutyDate The duty date of the assessment\r\n */\r\n\t\tfunction updateCrewMembers(CCMSPositions, Route, DutyDate) {\r\n\t\t\tvar assessment = getCrewAssessmentByRoute(Route, DutyDate);\r\n\t\t\tvar crewAssessmentTemplate = CrewAssessmentTemplateFactory.getCrewAssessmentTemplateFromStorage();\r\n\t\t\tvar routeFlights = FlightFactory.getFlightsByRoute(Route, DutyDate)\r\n\t\t\tvar isChanged = false;\r\n\r\n\t\t\tif (CCMSPositions != null && assessment != null) {\r\n\r\n\t\t\t\tfor (var i = 0; i < CCMSPositions.length; i++) {\r\n\t\t\t\t\tvar isExists = false;\r\n\r\n\t\t\t\t\tfor (var j = 0; j < assessment.CrewAssessmentMembers.length; j++) {\r\n\t\t\t\t\t\tif (CCMSPositions[i].CrewId == assessment.CrewAssessmentMembers[j].aimsId) {\r\n\t\t\t\t\t\t\tisExists = true;\r\n\r\n\t\t\t\t\t\t\tif (CCMSPositions[i].CCMS == \"N/A\") {\r\n\t\t\t\t\t\t\t\tvar isValid = false;\r\n\r\n\t\t\t\t\t\t\t\tfor (var h = 0; h < routeFlights.length; h++) {\r\n\t\t\t\t\t\t\t\t\tvar localReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(routeFlights[h].FlightId);\r\n\r\n\t\t\t\t\t\t\t\t\tif (localReport != null) {\r\n\t\t\t\t\t\t\t\t\t\tfor (var e = 0; e < localReport.CCMSCrewPositions.length; e++) {\r\n\t\t\t\t\t\t\t\t\t\t\tif (CCMSPositions[i].CrewId == localReport.CCMSCrewPositions[e].CrewId && localReport.CCMSCrewPositions[e].CCMS != \"N/A\") {\r\n\t\t\t\t\t\t\t\t\t\t\t\tisValid = true;\r\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t\tif (isValid) {\r\n\t\t\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tif (assessment.CrewAssessmentMembers[j].IsValid != isValid) {\r\n\t\t\t\t\t\t\t\t\tisChanged = true;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tassessment.CrewAssessmentMembers[j].IsValid = isValid;\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tif (!assessment.CrewAssessmentMembers[j].IsValid) {\r\n\t\t\t\t\t\t\t\t\tisChanged = true;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tassessment.CrewAssessmentMembers[j].IsValid = true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (!isExists && CCMSPositions[i].IsManual) {\r\n\t\t\t\t\t\tvar crewMember = CrewAssessmentMemberFactory.newMember();\r\n\t\t\t\t\t\tcrewMember.aimsId = CCMSPositions[i].CrewId;\r\n\t\t\t\t\t\tcrewMember.assessmentItems = crewAssessmentTemplate\r\n\t\t\t\t\t\tcrewMember.name = CCMSPositions[i].Name;\r\n\t\t\t\t\t\tcrewMember.position = CCMSPositions[i].Position;\r\n\t\t\t\t\t\tcrewMember.shortname = CCMSPositions[i].Initials;\r\n\t\t\t\t\t\tcrewMember.IsManual = true;\r\n\t\t\t\t\t\tcrewMember.IsCompleted = false;\r\n\t\t\t\t\t\tcrewMember.IsValid = (CCMSPositions[i].CCMS != \"N/A\");\r\n\t\t\t\t\t\tisChanged = true;\r\n\t\t\t\t\t\tassessment.CrewAssessmentMembers.push(crewMember);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tfor (var i = 0; i < assessment.CrewAssessmentMembers.length; i++) {\r\n\t\t\t\t\tfor (var h = 0; h < routeFlights.length; h++) {\r\n\t\t\t\t\t\tvar localReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(routeFlights[h].FlightId);\r\n\r\n\t\t\t\t\t\tif (localReport != null) {\r\n\t\t\t\t\t\t\tisExists = false;\r\n\r\n\t\t\t\t\t\t\tfor (var j = 0; j < localReport.CCMSCrewPositions.length; j++) {\r\n\t\t\t\t\t\t\t\tif (localReport.CCMSCrewPositions[j].CrewId == assessment.CrewAssessmentMembers[i].aimsId) {\r\n\t\t\t\t\t\t\t\t\tisExists = true;\r\n\t\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (!isExists) {\r\n\t\t\t\t\t\tif (assessment.CrewAssessmentMembers[i].IsValid) {\r\n\t\t\t\t\t\t\tisChanged = true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tassessment.CrewAssessmentMembers[i].IsValid = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (isChanged && assessment.Status != \"Pending\") {\r\n\t\t\t\t\tassessment.Status = \"Draft\";\r\n\t\t\t\t\tvar flights = FlightFactory.getFlightsFromStorage();\r\n\r\n\t\t\t\t\tfor (var i = 0; i < flights.length; i++) {\r\n\t\t\t\t\t\tif (flights[i].assessment && flights[i].assessment.Id == assessment.Id) {\r\n\t\t\t\t\t\t\tflights[i].assessment.Status = assessment.Status;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tFlightFactory.setFlightsToStorage(flights);\r\n\t\t\t\t}\r\n\t\t\t setCrewAssessmentToStorage(assessment);\r\n\t\t\t}\r\n\t\t}\r\n\r\n \r\n /**\r\n * Update Assessment from the new Assessment from Sync\r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} assessment The assessment\r\n * @param {Object} newAssessment The new assessment\r\n */\t\t\r\n\t\tfunction updateCrewAssessment(assessment, newAssessment) {\r\n\t\t\tvar crewAssessmentTemplate = CrewAssessmentTemplateFactory.getCrewAssessmentTemplateFromStorage();\r\n\t\t\tif (crewAssessmentTemplate == null) return assessment;\r\n\t\t\r\n\t\t\t// Load the flight\r\n\t\t\tvar flights = FlightFactory.getFlightsByRoute(assessment.Route, assessment.DutyDate);\r\n\t\t\tif (flights == null) return assessment;\r\n\t\t\r\n\t\t\tassessment.Flights = [];\r\n\t\t\tassessment.AcType = flights[0].AcType;\r\n\t\t\tassessment = updateAssessmentFlights(assessment, flights);\r\n\t\t\r\n\t\t\tvar isUpdated = false;\r\n\t\t\r\n\t\t\t// Flags to check member states\r\n\t\t\tvar validCrewCount = 0; // Non-outdated and exists\r\n\t\t\tvar outdatedCrewCount = 0; // Outdated\r\n\t\t\tvar nonExistentCrewCount = 0; // Non-outdated but doesn't exist\r\n\t\t\r\n\t\t\tfor (var i = 0; i < newAssessment.assessmentCrew.length; i++) {\r\n\t\t\t\tvar isCreated = false;\r\n\t\t\r\n\t\t\t\t// Update flags based on crew member status\r\n\t\t\t\tif (newAssessment.assessmentCrew[i].IsOutdated && !newAssessment.assessmentCrew[i].IsExist) {\r\n\t\t\t\t\toutdatedCrewCount++;\r\n\t\t\t\t} else if (!newAssessment.assessmentCrew[i].IsExist) {\r\n\t\t\t\t\tnonExistentCrewCount++;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvalidCrewCount++;\r\n\t\t\t\t}\r\n\t\t\r\n\t\t\t\tfor (var l = 0; l < assessment.CrewAssessmentMembers.length; l++) {\r\n\t\t\t\t\tif (newAssessment.assessmentCrew[i].CrewAimsId == assessment.CrewAssessmentMembers[l].aimsId ||\r\n\t\t\t\t\t\tnewAssessment.assessmentCrew[i].CrewId == assessment.CrewAssessmentMembers[l].Id) {\r\n\t\t\r\n\t\t\t\t\t\tassessment.CrewAssessmentMembers[l].aimsId = newAssessment.assessmentCrew[i].CrewAimsId;\r\n\t\t\t\t\t\tassessment.CrewAssessmentMembers[l].id = newAssessment.assessmentCrew[i].CrewId;\r\n\t\t\t\t\t\tassessment.CrewAssessmentMembers[l].name = newAssessment.assessmentCrew[i].Name;\r\n\t\t\t\t\t\tassessment.CrewAssessmentMembers[l].IsValid = true;\r\n\t\t\t\t\t\tassessment.CrewAssessmentMembers[l].IsOutdated = newAssessment.assessmentCrew[i].IsOutdated;\r\n\t\t\t\t\t\tassessment.CrewAssessmentMembers[l].EndPeriod = newAssessment.assessmentCrew[i].EndPeriod;\r\n\r\n\t\t\t\t\t\tvar newAssessmentItems = [];\r\n\t\t\r\n\t\t\t\t\t\tfor (var j = 0; j < crewAssessmentTemplate.length; j++) {\r\n\t\t\t\t\t\t\tvar question = {\r\n\t\t\t\t\t\t\t\tId: crewAssessmentTemplate[j].Id,\r\n\t\t\t\t\t\t\t\tDescription: crewAssessmentTemplate[j].Description,\r\n\t\t\t\t\t\t\t\tLabel: crewAssessmentTemplate[j].Label,\r\n\t\t\t\t\t\t\t\tOrderNo: crewAssessmentTemplate[j].OrderNo,\r\n\t\t\t\t\t\t\t\tItemValue: crewAssessmentTemplate[j].ItemValue,\r\n\t\t\t\t\t\t\t\tItemDescr: null\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tif (assessment.CrewAssessmentMembers[l].assessmentItems) {\r\n\t\t\t\t\t\t\t\tfor (var h = 0; h < assessment.CrewAssessmentMembers[l].assessmentItems.length; h++) {\r\n\t\t\t\t\t\t\t\t\tif (crewAssessmentTemplate[j].Id == assessment.CrewAssessmentMembers[l].assessmentItems[h].Id) {\r\n\t\t\t\t\t\t\t\t\t\tquestion.ItemValue = assessment.CrewAssessmentMembers[l].assessmentItems[h].ItemValue;\r\n\t\t\t\t\t\t\t\t\t\tquestion.ItemDescr = assessment.CrewAssessmentMembers[l].assessmentItems[h].ItemDescr;\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tnewAssessmentItems.push(question);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tassessment.CrewAssessmentMembers[l].assessmentItems = newAssessmentItems;\r\n\t\t\r\n\t\t\t\t\t\tif (assessment.CrewAssessmentMembers[l].IsExist != newAssessment.assessmentCrew[i].IsExist) {\r\n\t\t\t\t\t\t\tassessment.CrewAssessmentMembers[l].IsExist = newAssessment.assessmentCrew[i].IsExist;\r\n\t\t\t\t\t\t\tisUpdated = true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tisCreated = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (!isCreated) {\r\n\t\t\t\t\tvar crewMember = CrewAssessmentMemberFactory.newMember();\r\n\t\t\t\t\tcrewMember.aimsId = newAssessment.assessmentCrew[i].CrewAimsId;\r\n\t\t\t\t\tcrewMember.id = newAssessment.assessmentCrew[i].CrewId;\r\n\t\t\t\t\tcrewMember.assessmentItems = crewAssessmentTemplate;\r\n\t\t\t\t\tcrewMember.name = newAssessment.assessmentCrew[i].Name;\r\n\t\t\t\t\tcrewMember.IsCompleted = false;\r\n\t\t\t\t\tcrewMember.IsValid = true;\r\n\t\t\t\t\tcrewMember.IsExist = newAssessment.assessmentCrew[i].IsExist;\r\n\t\t\t\t\tcrewMember.IsOutdated = newAssessment.assessmentCrew[i].IsOutdated;\r\n\t\t\t\t\tcrewMember.EndPeriod = newAssessment.assessmentCrew[i].EndPeriod;\r\n\t\t\t\r\n\t\t\t\t\tassessment.CrewAssessmentMembers.push(crewMember);\r\n\t\t\t\t\tisUpdated = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\r\n\t\t\tfor (var l = 0; l < assessment.CrewAssessmentMembers.length; l++) {\r\n\t\t\t\tvar isExists = false;\r\n\t\t\t\tfor (var i = 0; i < newAssessment.assessmentCrew.length; i++) {\r\n\t\t\t\t\tif (newAssessment.assessmentCrew[i].CrewAimsId == assessment.CrewAssessmentMembers[l].aimsId ||\r\n\t\t\t\t\t\tnewAssessment.assessmentCrew[i].CrewId == assessment.CrewAssessmentMembers[l].Id) {\r\n\t\t\t\t\t\tisExists = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (!isExists && !assessment.CrewAssessmentMembers[l].IsManual) {\r\n\t\t\t\t\tassessment.CrewAssessmentMembers.splice(l, 1);\r\n\t\t\t\t\tl--; // Adjust index after removal\r\n\t\t\t\t\tisUpdated = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Update the Status based on the flags\r\n\t\t\tif (validCrewCount > 0) {\r\n\t\t\t\t// If there's at least one valid (non-outdated and existing) crew member\r\n\t\t\t\tassessment.Status = \"Stored\";\r\n\t\t\t} else if (outdatedCrewCount > 0 && nonExistentCrewCount === 0) {\r\n\t\t\t\t// All members are outdated\r\n\t\t\t\tassessment.Status = \"Outdated\";\r\n\t\t\t} else if (nonExistentCrewCount > 0) {\r\n\t\t\t\t// If there are non-outdated but non-existent members\r\n\t\t\t\tassessment.Status = \"Pending\";\r\n\t\t\t} else if (isUpdated && assessment.Status == \"Stored\") {\r\n\t\t\t\t// If there were updates and it was stored before, downgrade to Draft\r\n\t\t\t\tassessment.Status = \"Draft\";\r\n\t\t\t}\r\n\t\t\r\n\t\t\tassessment.assessedBy = newAssessment.assessedBy;\r\n\t\t\r\n\t\t\t// Update IsExist based on the flag\r\n\t\t\tassessment.IsExist = validCrewCount > 0;\r\n\t\t\r\n\t\t\treturn assessment;\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Get only the reports that have a stored or complete Assessment\r\n * @memberof CrewAssessmentFactory\r\n * @returns {Array} crewAssesments \r\n */\r\n\t\tfunction getAssesedCabinReports() { \r\n\t\t\tvar reports = CabinReportLocalEditFactory.getCabinReportsFromStorage();\r\n\t\t\tvar assessments = getCrewAssessmentsFromStorage();\r\n\r\n\t\t\tvar assesedReports = [];\r\n\r\n\t\t\tfor (var i = 0; i < assessments.length; i++) {\r\n\t\t\t\tif (assessments[i].Status != \"Completed\" && !assessments[i].IsExist && assessments[i].CrewAssessmentMembers.length > 0) {\r\n\t\t\t\t\tvar isCompleted = true;\r\n\t\t\t\t\tvar routeReports = [];\r\n\t\t\t\t\tfor (var j = 0; j < reports.length; j++) {\r\n\t\t\t\t\t\tif (reports[j].Route == assessments[i].Route && reports[j].DutyDate == assessments[i].DutyDate) {\r\n\t\t\t\t\t\t\tif (reports[j].Status != \"completed\") {\r\n\t\t\t\t\t\t\t\tisCompleted = false;\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\trouteReports.push(reports[j]);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (isCompleted) {\r\n\t\t\t\t\t\tvar flights = FlightFactory.getFlightsByRoute(assessments[i].Route, assessments[i].DutyDate);\r\n\t\t\t\t\t\tfor (var j = 0; j < flights.length; j++) {\r\n\t\t\t\t\t\t\tif (flights[j].cabinReportStatusDescr == \"Pending\") {\r\n\t\t\t\t\t\t\t\tisCompleted = false\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (!isCompleted) {\r\n\t\t\t\t\t\tassesedReports = assesedReports.concat(routeReports);\r\n\t\t\t\t\t} else if (routeReports != []) {\r\n\t\t\t\t\t\trouteReports.sort(function(a, b) {\r\n\t\t\t\t\t\t\treturn (new Date(b.ScheduledDeparture) - new Date(a.ScheduledDeparture))\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\trouteReports.splice(0, 1);\r\n\t\t\t\t\t\tassesedReports = assesedReports.concat(routeReports);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t} else {\r\n\t\t\t\t\tfor (var j = 0; j < reports.length; j++) {\r\n\t\t\t\t\t\tif (reports[j].Route == assessments[i].Route && reports[j].DutyDate == assessments[i].DutyDate) {\r\n\t\t\t\t\t\t\tif (reports[j].Status == \"completed\") {\r\n\t\t\t\t\t\t\t\tassesedReports.push(reports[j]);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t//orphaned reports\r\n\t\t\tfor (var j = 0; j < reports.length; j++) {\r\n\t\t\t\tif (!existsForRouteDutyDate(reports[j].Route, reports[j].DutyDate)) {\r\n\t\t\t\t\tif (reports[j].Status == \"completed\") {\r\n\t\t\t\t\t\tassesedReports.push(reports[j]);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn assesedReports;\r\n\t\t\t}\r\n\r\n /**\r\n * Find if an assessment exists for the selected Route and Duty Date\r\n * @memberof CrewAssessmentFactory\r\n * @param {string} Route The route of the assessment\r\n * @param {string} DutyDate The duty date of the assessment\r\n * @returns {boolean} isExist \r\n */\r\n\t\tfunction existsForRouteDutyDate(Route, DutyDate) {\r\n\t\t\tvar assessments = getCrewAssessmentsFromStorage();\r\n\r\n\t\t\tvar isExist = false;\r\n\t\t\tfor (var j = 0; j < assessments.length; j++) {\r\n\t\t\t\tif (assessments[j].Route == Route && assessments[j].DutyDate == DutyDate) {\r\n\t\t\t\t\tisExist = true;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn isExist;\r\n\t\t}\r\n\r\n /**\r\n * Update Assessment Information from flights\r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} crewAssessment The crew assessment\r\n * @param {Array} flights The flights of the Assessment\r\n */\r\n function updateAssessmentFlights(crewAssessment,flights){\r\n\t\t\tfor (var i = 0; i < flights.length; i++) {\r\n if(crewAssessment.start && crewAssessment.end){\r\n var flightStart = Date.parse(flights[i].ScheduledDeparture);\r\n var flightEnd = Date.parse(flights[i].ScheduledArrival);\r\n \r\n var assesmentStart = Date.parse(crewAssessment.start);\r\n if (flightStartassesmentEnd){\r\n crewAssessment.end = flights[i].ScheduledArrival;\r\n } \r\n }\r\n }else{\r\n crewAssessment.start = flights[i].ScheduledDeparture;\r\n crewAssessment.end = flights[i].ScheduledArrival;\r\n }\r\n \r\n\t\t\t\tvar flight = {\r\n\t\t\t\t\tScheduledDepartureDateUTC: flights[i].ScheduledDepartureDateUTC,\r\n\t\t\t\t\tFlightNo: flights[i].FlightNo,\r\n\t\t\t\t\tDeparture: flights[i].Departure,\r\n\t\t\t\t\tArrival: flights[i].Arrival,\r\n\t\t\t\t\tScheduledDepartureTimeUTC: flights[i].ScheduledDepartureTimeUTC,\r\n ScheduledDeparture: flights[i].ScheduledDeparture,\r\n\t\t\t\t\tScheduledArrival: flights[i].ScheduledArrival,\r\n\t\t\t\t\tAcTailNo: flights[i].AcTailNo\r\n\t\t\t\t}\r\n\t\t\t\tcrewAssessment.Flights.push(flight);\r\n\t\t\t}\r\n \r\n return crewAssessment;\r\n }\r\n \r\n /**\r\n * Returns the a list of cabin Crew Feedbacks that are ready to send (the reports of the assessment are completed or synched)\r\n * @memberof CrewAssessmentFactory\r\n * @param {string} Route The route of the assessment\r\n * @param {string} DutyDate The duty date of the assessment\r\n * @returns {Array} assessmentsToSend \r\n */\r\n\t\tfunction getAssementsReadyToSend() {\r\n\t\t\tvar assessments = getCrewAssessmentsFromStorage();\r\n\t\t\tvar assessmentsToSend = [];\r\n\t\t\tfor (var i = 0; i < assessments.length; i++) {\r\n\t\t\t\tif (assessments[i].Status == \"Completed\") {\r\n\r\n\t\t\t\t\tassessmentsToSend.push(assessments[i]);\r\n\t\t\t\t\t\r\n\t\t\t\t\t////Send assessments anyway...\r\n\t\t\t\t\t// var isCompleted = true;\r\n\t\t\t\t\t// var flights = FlightFactory.getFlightsByRoute(assessments[i].Route, assessments[i].DutyDate);\r\n\t\t\t\t\t// for (var j = 0; j < flights.length; j++) {\r\n\t\t\t\t\t// \tif (flights[j].LineStatus == \"pending\" || flights[j].LineStatus == \"pendingoverdue\" || flights[j].LineStatus == \"draft\") {\r\n\t\t\t\t\t// \t\tisCompleted = false;\r\n\t\t\t\t\t// \t\tbreak;\r\n\t\t\t\t\t// \t}\r\n\t\t\t\t\t// }\r\n\t\t\t\t\t// if (isCompleted) {\r\n\t\t\t\t\t// \tassessmentsToSend.push(assessments[i])\r\n\t\t\t\t\t// }\r\n\t\t\t\t}\r\n\r\n\t\t\t}\r\n\t\t\treturn assessmentsToSend;\r\n\t\t}\r\n\r\n /**\r\n * Store Assessment inside the flights\r\n * @memberof CrewAssessmentFactory\r\n */\r\n\t\tfunction storeFlightsWithAssessments() {\r\n\t\t\tvar flights = FlightFactory.getFlightsFromStorage();\r\n\t\t\tvar crewAssessments = getCrewAssessmentsFromStorage();\r\n\t\t\tfor (var i = 0; i < flights.length; i++) {\r\n\t\t\t\tfor (var j = 0; j < crewAssessments.length; j++) {\r\n\t\t\t\t\tif (flights[i].Route == crewAssessments[j].Route && flights[i].DutyDate == crewAssessments[j].DutyDate) {\r\n\t\t\t\t\t\tflights[i].assessment = {\r\n\t\t\t\t\t\t\tId: crewAssessments[j].Id,\r\n\t\t\t\t\t\t\tStatus: crewAssessments[j].Status,\r\n\t\t\t\t\t\t\tIsExist: crewAssessments[j].IsExist,\r\n\t\t\t\t\t\t\tIsAssessedBy: crewAssessments[j].assessedBy.length > 0,\r\n\t\t\t\t\t\t\tIsCrewLess: crewAssessments[j].CrewAssessmentMembers.length < 1\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tFlightFactory.setFlightsToStorage(flights);\r\n\t\t}\r\n\r\n /**\r\n * Update Assessments which are stored inside the flights \r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} crewAssessment The crew assessment\\\r\n */\r\n\t\tfunction updateFlightsAssessment(assessment) {\r\n\t\t\tvar flights = FlightFactory.getFlightsFromStorage();\r\n\t\t\tfor (var i = 0; i < flights.length; i++) {\r\n\t\t\t\tif (flights[i].assessment && flights[i].assessment.Id == assessment.Id) {\r\n\t\t\t\t\tflights[i].assessment.Status = assessment.Status;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tFlightFactory.setFlightsToStorage(flights);\r\n\t\t}\r\n\r\n /**\r\n * Store Assessment inside the crewRoutes\r\n * @memberof CrewAssessmentFactory\r\n */\r\n\t\tfunction storeCrewRoutesWithAssessments() {\r\n\t\t\tvar crewRoutes = CrewRouteFactory.getCrewRoutesFromStorage();\r\n\t\t\tvar crewAssessments = getCrewAssessmentsFromStorage();\r\n\t\t\tfor (var i = 0; i < crewRoutes.length; i++) {\r\n\t\t\t\tfor (var j = 0; j < crewAssessments.length; j++) {\r\n\t\t\t\t\tif (crewRoutes[i].Route == crewAssessments[j].Route && crewRoutes[i].DutyDay == crewAssessments[j].DutyDay) {\r\n\t\t\t\t\t\tcrewRoutes[i].AssessmentInfo = {\r\n\t\t\t\t\t\t\tId: crewAssessments[j].Id,\r\n\t\t\t\t\t\t\tStatus: crewAssessments[j].Status,\r\n\t\t\t\t\t\t\tIsExist: crewAssessments[j].IsExist,\r\n\t\t\t\t\t\t\t// IsAssessedBy: crewAssessments[j].assessedBy.length > 0,\r\n\t\t\t\t\t\t\t// IsCrewLess: crewAssessments[j].CrewAssessmentMembers.length < 1,\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tCrewRouteFactory.setCrewRoutesToStorage(crewRoutes);\r\n\t\t}\r\n\r\n /**\r\n * Update Assessments which are stored inside the crewRoute \r\n * @memberof CrewAssessmentFactory\r\n * @param {Object} crewAssessment The crew assessment\\\r\n */\r\n\t\tfunction updateCrewRouteAssessment(assessment) {\r\n\t\t\tvar crewRoutes = CrewRouteFactory.getCrewRoutesFromStorage();\r\n\t\t\tfor (var i = 0; i < crewRoutes.length; i++) {\r\n\t\t\t\tif (crewRoutes[i].AssessmentInfo && crewRoutes[i].AssessmentInfo.Id == assessment.Id) {\r\n\t\t\t\t\tcrewRoutes[i].AssessmentInfo.Status = assessment.Status;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tCrewRouteFactory.setCrewRoutesToStorage(crewRoutes);\r\n\t\t}\r\n\treturn service;\r\n\t}\r\n \r\n})();","(function() {\r\n 'use strict';\r\na3_cabin_reports.factory('CrewAssessmentCreatorFactory', CrewAssessmentCreatorFactory);\r\n\t\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewAssessmentCreatorFactory\r\n * @description \r\n * Initializes new Crew Assessments\r\n * @ngInject\r\n */ \r\nfunction CrewAssessmentCreatorFactory(UserFactory, CrewAssessmentFactory, CrewAssessmentTemplateFactory, FlightFactory, CrewAssessmentMemberFactory) {\r\n\r\n\t\tvar service = \r\n\t\t{\r\n\t\t\tcreateNewCrewAssessment : createNewCrewAssessment,\r\n\t\t\tcreateCrewAssessments : createCrewAssessments\r\n\t\t}\r\n\r\n /**\r\n * Create New Crew Assessment from the api assessments\r\n * @memberof CrewAssessmentCreatorFactory\r\n * @returns {object} assessment \r\n */\r\n\t\tfunction createNewCrewAssessment(assessment) {\r\n\t\t\t// load the user\r\n\t\t\tvar user = UserFactory.getUser();\r\n\t\t\tif (user == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\t// load the crewAssessmentTemplate\r\n\t\t\tvar crewAssessmentTemplates = CrewAssessmentTemplateFactory.getCrewAssessmentTemplateFromStorage();\r\n\t\t\tif (crewAssessmentTemplates == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\t// load the flight\r\n\t\t\tvar flights = FlightFactory.getFlightsByRoute(assessment.Route, assessment.DutyDate);\r\n\t\t\tif (flights == null || flights.length==0)\r\n\t\t\t\treturn null;\r\n\r\n\r\n\t\t\t// create the new crewAssessment\r\n\t\t\tvar crewAssessment = CrewAssessmentFactory.getNewCrewAssessment();\r\n\r\n\t\t\tcrewAssessment.Id = (assessment.Id == null) ? guid() : assessment.Id;\r\n\t\t\tcrewAssessment.UserId = user.id;\r\n\t\t\tcrewAssessment.Route = assessment.Route;\r\n\t\t\tcrewAssessment.DutyDate = assessment.DutyDate;\r\n\t\t\tcrewAssessment.DutyDay = assessment.DutyDay;\r\n\r\n crewAssessment.AcType = flights[0].AcType;\r\n\t\t\tcrewAssessment = CrewAssessmentFactory.updateAssessmentFlights(crewAssessment,flights);\r\n\r\n\t\t\tcrewAssessment.assessedBy = assessment.assessedBy;\r\n\t\t\tvar IsExist = true\r\n\r\n\t\t\tfor (var i = 0; i < assessment.assessmentCrew.length; i++) {\r\n\t\t\t\tvar crewMember = CrewAssessmentMemberFactory.newMember();\r\n\t\t\t\tcrewMember.aimsId = assessment.assessmentCrew[i].CrewAimsId;\r\n\t\t\t\tcrewMember.id = assessment.assessmentCrew[i].CrewId;\r\n\t\t\t\tcrewMember.assessmentItems = crewAssessmentTemplates;\r\n\t\t\t\tcrewMember.name = assessment.assessmentCrew[i].Name;\r\n\t\t\t\tcrewMember.IsCompleted = false;\r\n\t\t\t\tcrewMember.IsValid = true;\r\n\t\t\t\tcrewMember.IsExist = assessment.assessmentCrew[i].IsExist;\r\n\t\t\t\tcrewMember.IsOutdated = assessment.assessmentCrew[i].IsOutdated;\r\n\t\t\t\tcrewMember.EndPeriod = assessment.assessmentCrew[i].EndPeriod;\r\n\r\n\t\t\t\tif (!assessment.assessmentCrew[i].IsExist) {\r\n\t\t\t\t\tIsExist = false;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tcrewAssessment.CrewAssessmentMembers.push(crewMember);\r\n\t\t\t}\r\n\r\n\r\n\t\t\tcrewAssessment.IsExist = IsExist;\r\n\t\t\tif(IsExist){\r\n\t\t\t\tcrewAssessment.Status = \"Stored\";\r\n\t\t\t}\r\n\t\t\t// return the new crewAssessment\r\n\t\t\treturn crewAssessment;\r\n\t\t}\r\n\r\n /**\r\n * Create New Crew Assessments from the api assessments\r\n * @memberof CrewAssessmentCreatorFactory\r\n * @returns {Array} crewAssessments \r\n */\r\n\t\tfunction createCrewAssessments(assessments) {\r\n\t\t\tvar crewAssessments = [];\r\n\t\t\tfor (var i = 0; i < assessments.length; i++) {\r\n\t\t\t\tvar crewAssessment = createNewCrewAssessment(assessments[i])\r\n if(crewAssessment){\r\n crewAssessments.push(crewAssessment);\r\n }\r\n\t\t\t\t\r\n\t\t\t}\r\n\t\t\treturn crewAssessments;\r\n\t\t}\r\n \r\n\r\n\t\treturn service;\r\n\t}\r\n \r\n})();","(function() {\r\n 'use strict';\r\na3_cabin_reports.factory('CrewAssessmentMemberFactory', CrewAssessmentMemberFactory)\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewAssessmentMemberFactory\r\n * @description \r\n * Initializes new Crew Assessment Members\r\n * @ngInject\r\n */ \r\nfunction CrewAssessmentMemberFactory() {\r\n\r\n /**\r\n * Initialize the Crew Assessment Member\r\n * @memberof CrewAssessmentMemberFactory\r\n */\r\n\t\tfunction CrewAssessmentMember() {\r\n\t\t\tthis.aimsId = null;\r\n\t\t\tthis.id = null;\r\n\t\t\tthis.name = null;\r\n\t\t\tthis.IsCompleted = false;\r\n\t\t\tthis.IsValid = true;\r\n\t\t\tthis.IsOverride = false;\r\n\t\t\tthis.IsManual = false;\r\n\t\t\tthis.IsExist = false;\r\n this.Review = null;\r\n\t\t\tthis.assessmentItems = [];\r\n this.IsOutdated = false;\r\n this.EndPeriod = null;\r\n\t\t}\r\n\r\n\t\tvar service = \r\n\t\t{\r\n\t\t\tnewMember : newMember\r\n\t\t}\r\n\r\n /**\r\n * Create New Crew Assessment Member\r\n * @memberof CrewAssessmentMemberFactory\r\n * @returns {object} CrewAssessmentMember \r\n */\r\n\t\tfunction newMember() {\r\n\t\t\treturn new CrewAssessmentMember();\r\n\t\t}\r\n\r\n\treturn service;\r\n}\r\n \r\n})();","(function() {\r\n 'use strict';\r\na3_cabin_reports.factory('CrewAssessmentTemplateFactory', CrewAssessmentTemplateFactory);\r\n\r\n/**\r\n* @memberof CabinReports\r\n* @ngdoc factory\r\n* @name CrewAssessmentTemplateFactory\r\n* @description \r\n* Get,Set new Crew Assessment Templates\r\n* @ngInject\r\n*/ \r\nfunction CrewAssessmentTemplateFactory(GenericService){\r\n\r\n /**\r\n * Initialize the Crew Assessment Template\r\n * @memberof CrewAssessmentTemplateFactory\r\n */\r\n\t\tfunction CrewAssessmentTemplate() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.Description = null;\r\n\t\t\tthis.Label = null;\r\n\t\t\tthis.OrderNo = null;\r\n\t\t\tthis.ItemValue = 3;\r\n\t\t\tthis.GetId = GetId;\r\n\t\t}\r\n\r\n\t\tvar objType = 'CrewAssessmentTemplate';\r\n\t\tvar objCallback = CrewAssessmentTemplate; \r\n\t\t\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tgetCrewAssessmentTemplateFromStorage : getCrewAssessmentTemplateFromStorage,\r\n\t\t\tsetCrewAssessmentTemplateToStorage : setCrewAssessmentTemplateToStorage\r\n\t\t};\r\n\t\t\t\r\n\t\t//Object services\r\n /**\r\n * Overide default get Id\r\n * @memberof CrewAssessmentTemplateFactory\r\n * @returns {number} Id \r\n */\r\n\t\tfunction GetId(){\r\n\t\t\treturn this.Id;\r\n\t\t}\r\n\t\t\r\n\t\t// Factory Services\r\n /**\r\n * Get Crew Assessment Templates\r\n * @memberof CrewAssessmentTemplateFactory\r\n * @returns {Array} CrewAssessmentTemplates \r\n */\r\n\t\tfunction getCrewAssessmentTemplateFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get Assessment Sync Results\r\n * @memberof CrewAssessmentTemplateFactory\r\n * @param {Array} CrewAssessmentTemplates A list of Crew assesment template questions\r\n */\r\n\t\tfunction setCrewAssessmentTemplateToStorage(crewAssessmentTemplate) {\r\n\t\t\tGenericService.saveAll(crewAssessmentTemplate,objType,objCallback);\r\n\t\t}\r\n\r\n\r\n\treturn service;\r\n}\r\n\t\r\n \r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.factory('CampaignFactory', CampaignFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CampaignFactory\r\n * @description \r\n * Add, Update, Delete and Get Campaigns.\r\n * @ngInject\r\n */\r\n\tfunction CampaignFactory(GenericService, FlightFactory) {\r\n\r\n\t\tvar objType = 'Campaigns';\r\n\t\tvar objCallback = Campaign;\r\n\r\n /**\r\n * Initialize the Campaign\r\n * @memberof CampaignFactory\r\n */\r\n\t\tfunction Campaign() {\r\n\t\t\tthis.GetId = GetId;\r\n\t\t}\r\n\r\n\t\tvar service = {\r\n\t\t\tgiftStatusList: giftStatusList,\r\n\t\t\tgetFlightsCampaignsFromStorage: getFlightsCampaignsFromStorage,\r\n\t\t\tgetCampaignsByFlightId: getCampaignsByFlightId,\r\n\t\t\tsaveFlightCampaignsToStorage: saveFlightCampaignsToStorage,\r\n\t\t\tupdateCampaignPassenger: updateCampaignPassenger,\r\n\t\t\tupdateSeatNoPaxAssignments: updateSeatNoPaxAssignments,\r\n\t\t\tgetPaxAssignmentsFromStorage: getPaxAssignmentsFromStorage,\r\n\t\t\tmergeCampaigns: mergeCampaigns,\r\n\t\t\tgetPaxAssignment: getPaxAssignment,\r\n\t\t\thasPendingFeedbacks: hasPendingFeedbacks,\r\n\t\t\tsyncResultFormat: syncResultFormat,\r\n\t\t\tcleanOldCampaigns: cleanOldCampaigns\r\n\t\t};\r\n\r\n\t\t//Object Functions\r\n /**\r\n * Overide default get Id\r\n * @memberof FlightFactory\r\n * @returns {number} Id \r\n */\r\n\t\tfunction GetId() {\r\n\t\t\treturn this.FlightId;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t * Get Campaigns\r\n\t * @memberof CampaignFactory\r\n\t * @param {function} callback \r\n\t */\r\n\t\tfunction getFlightsCampaignsFromStorage() {\r\n\t\t\treturn GenericService.list(objType, objCallback);\r\n\t\t};\r\n\r\n /**\r\n * Save Campaigns to storage\r\n * @memberof CampaignFactory\r\n * @param {Array} flightCampaigns A list of flightCampaigns\r\n */\r\n\t\t function setFlightCampaignsToStorage(flightCampaigns) {\r\n\t\t\tGenericService.saveAll(flightCampaigns,objType,objCallback);\r\n\t\t}\r\n \r\n\t\t/**\r\n\t\t* Get single flight Campaigns\r\n\t\t* @memberof CampaignFactory\r\n\t\t* @param {function} callback \r\n\t\t*/\r\n\t\tfunction getCampaignsByFlightId(flightId) {\r\n\t\t\treturn GenericService.get(flightId, objType, objCallback);\r\n\t\t};\r\n\r\n\t\t/**\r\n\t\t* Set single flight Campaigns\r\n\t\t* @memberof CampaignFactory\r\n\t\t* @param {function} callback \r\n\t\t*/\r\n\t\tfunction addFlightCampaigns(FlightCampaigns) {\r\n\t\t\tFlightCampaigns.IsFeedbackReady = !hasPendingFeedbacks(FlightCampaigns);\r\n\t\t\treturn GenericService.add(FlightCampaigns, objType, objCallback);\r\n\t\t};\r\n\r\n\r\n\t\t/**\r\n\t\t* Get assignments from storage\r\n\t\t* @memberof CampaignFactory\r\n\t\t* @param {function} callback \r\n\t\t*/\r\n\t\tfunction getPaxAssignmentsFromStorage() {\r\n\t\t\tvar assignmentsToSend = [];\r\n\t\t\tvar data = getFlightsCampaignsFromStorage();\r\n\r\n\t\t\tif (data) {\r\n\t\t\t\tvar flightsReadyList = data.filter(function (d) { return d.IsFeedbackReady });\r\n\r\n\t\t\t\tfor (let flight of flightsReadyList) {\r\n\r\n\t\t\t\t\tvar flightStored = FlightFactory.getFlightFromStorage(flight.FlightId);\r\n\t\t\t\t\tvar isSyncTimeValid = flightStored == null || moment().valueOf() > moment.utc(flightStored.ScheduledDeparture).valueOf();\r\n\r\n\t\t\t\t\tif (isSyncTimeValid) {\r\n\t\t\t\t\t\tflight.CampaignsList.forEach(function (camp) {\r\n\t\t\t\t\t\t\tcamp.Treatments.forEach(function (treat) {\r\n\t\t\t\t\t\t\t\ttreat.Assignments.forEach(function (assign) {\r\n\t\t\t\t\t\t\t\t\tvar assignToSend = { ...assign, Status: +assign.StatusStr }\r\n\t\t\t\t\t\t\t\t\tassignmentsToSend.push(assignToSend);\r\n\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// else{\r\n\t\t\t\t\t// clearFlightCampaignsFromStorage(flight.FlightId)\r\n\t\t\t\t\t// }\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn {\r\n\t\t\t\t\tFlightsToFetch: data.map(function (flt) { return flt.FlightId }),\r\n\t\t\t\t\tAssignmentsToUpdate: assignmentsToSend\r\n\t\t\t\t};\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\t/**\r\n\t\t* Get assignment from storage with flightId, PNR, UCI\r\n\t\t* @memberof CampaignFactory\r\n\t\t* @param {function} callback \r\n\t\t*/\r\n\t\tfunction getPaxAssignment(flightId, pnr, uci) {\r\n\t\t\tvar fltCampaigns = getCampaignsByFlightId(flightId);\r\n\r\n\t\t\tvar data = {\r\n\t\t\t\tcampaign: null,\r\n\t\t\t\ttreatment: null,\r\n\t\t\t\tassignment: null\r\n\t\t\t};\r\n\r\n\t\t\tif (fltCampaigns) {\r\n\r\n\t\t\t\tfor (let camp of fltCampaigns.CampaignsList) {\r\n\r\n\t\t\t\t\tdata.campaign = { title: camp.CampaignTitle, briefings: camp.Briefings };\r\n\r\n\t\t\t\t\tfor (let treat of camp.Treatments) {\r\n\t\t\t\t\t\tdata.treatment = { title: treat.Title, description: treat.Description, briefings: treat.Briefings };\r\n\t\t\t\t\t\tdata.assignment = treat.Assignments.find(function (a) { return a.UCI == uci && a.PNR == pnr });\r\n\r\n\t\t\t\t\t\tif (data.assignment) break;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (data.assignment) break;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn data;\r\n\t\t}\r\n\r\n\t\tfunction mergeCampaigns(data) {\r\n\r\n\t\t\t//Current flights to store\r\n\t\t\tvar flightIdList = getFlightsCampaignsFromStorage().map(function (x) { return x.FlightId });\r\n\r\n\t\t\tif (data.UpdateAssignmentsSuccess) {\r\n\t\t\t\tvar incomingfltIds = data.FlightsCampaigns.map(function (x) { return x.FlightId });\r\n\t\t\t\tflightIdList.forEach(function (id) {\r\n\t\t\t\t\tif (!incomingfltIds.includes(id)) {\r\n\t\t\t\t\t\tclearFlightCampaignsFromStorage(id);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\tif (data.GetAssignmentsSuccess) {\r\n\t\t\t\tupdateIncomingStore(data.FlightsCampaigns);\r\n\r\n\t\t\t\tdata.FlightsCampaigns.forEach(function (flight) {\r\n\t\t\t\t\t//curent store not include incoming flight\r\n\t\t\t\t\tif (!flightIdList.includes(flight.FlightId))\r\n\t\t\t\t\t\taddFlightCampaigns(flight);\r\n\t\t\t\t\t//current store include flight\t\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tsaveFlightCampaignsToStorage(flight);\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction updateIncomingStore(incomingCamps) {\r\n\t\t\tfor (let flt of incomingCamps) {\r\n\t\t\t\tfor (let camp of flt.CampaignsList) {\r\n\t\t\t\t\tfor (let treat of camp.Treatments) {\r\n\t\t\t\t\t\tfor (let assign of treat.Assignments) {\r\n\t\t\t\t\t\t\tvar currentAssignment = findCurrentAssignment(assign);\r\n\r\n\t\t\t\t\t\t\tif (currentAssignment) { //&& ((assign.AutoSet && !currentAssignment.AutoSet) || (!assign.AutoSet && !currentAssignment.AutoSet))) {\r\n\t\t\t\t\t\t\t\tassign.Status = currentAssignment.Status;\r\n\t\t\t\t\t\t\t\tassign.StatusStr = currentAssignment.StatusStr;\r\n\t\t\t\t\t\t\t\tassign.Rate = currentAssignment.Rate;\r\n\t\t\t\t\t\t\t\tassign.Comments = currentAssignment.Comments;\r\n\t\t\t\t\t\t\t\t//assign.AutoSet = currentAssignment.Status != 5 ? false : currentAssignment.AutoSet;\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction findCurrentAssignment(assignment) {\r\n\t\t\tvar currentCamps = getFlightsCampaignsFromStorage();\r\n\t\t\tvar currentAssignment;\r\n\r\n\t\t\tfor (let flt of currentCamps) {\r\n\t\t\t\tfor (let camp of flt.CampaignsList) {\r\n\t\t\t\t\tfor (let treat of camp.Treatments) {\r\n\r\n\t\t\t\t\t\tcurrentAssignment = treat.Assignments.find(function (assign) { return assign.Id == assignment.Id });\r\n\t\t\t\t\t\tif (currentAssignment) break;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (currentAssignment) break;\r\n\t\t\t\t}\r\n\t\t\t\tif (currentAssignment) break;\r\n\t\t\t}\r\n\r\n\t\t\treturn currentAssignment;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Update FlightCampaigns to Storage\r\n\t\t * @memberof CampaignFactory\r\n\t\t * @param {object} CampaignPassenger a CampaignPassenger\r\n\t\t */\r\n\t\tfunction saveFlightCampaignsToStorage(campaignPassenger) {\r\n\t\t\tcampaignPassenger.IsFeedbackReady = !hasPendingFeedbacks(campaignPassenger);\r\n\t\t\tGenericService.save(campaignPassenger, objType, objCallback);\r\n\t\t};\r\n\r\n\t\tfunction updateCampaignPassenger(flightId, assignment) {\r\n\r\n\t\t\tvar data = getCampaignsByFlightId(flightId);\r\n\t\t\tvar assignmentLs;\r\n\r\n\t\t\tif (data) {\r\n\r\n\t\t\t\tvar fltCampaings = { ...data };\r\n\r\n\t\t\t\tfor (let camp of fltCampaings.CampaignsList) {\r\n\t\t\t\t\tfor (let treat of camp.Treatments) {\r\n\r\n\t\t\t\t\t\tassignmentLs = treat.Assignments.find(function (a) { return a.Id == assignment.Id });\r\n\r\n\t\t\t\t\t\tif (assignmentLs) {\r\n\t\t\t\t\t\t\tassignmentLs.Status = +assignment.StatusStr;\r\n\t\t\t\t\t\t\tassignmentLs.StatusStr = assignment.StatusStr;\r\n\t\t\t\t\t\t\tassignmentLs.Rate = +assignment.StatusStr == 1 ? assignment.Rate : 0;\r\n\t\t\t\t\t\t\tassignmentLs.Comments = assignment.Comments;\r\n\t\t\t\t\t\t\t//delete assignmentLs[\"AutoSet\"];\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (assignmentLs) break;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tsaveFlightCampaignsToStorage(fltCampaings);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction updateSeatNoPaxAssignments(fltCampaings, paxinfoList) {\r\n\r\n\t\t\tfltCampaings.forEach(function (fltcamp) {\r\n\t\t\t\tfltcamp.CampaignsList.forEach(function (camp) {\r\n\t\t\t\t\tvar paxinfo = paxinfoList.find(function (p) { return p.FlightId == fltcamp.FlightId });\r\n\t\t\t\t\tif (paxinfo) {\r\n\r\n\t\t\t\t\t\tvar paxinfoFlatten = flatten(paxinfo.Seatmap.map(function (s) { return s.Columns }));\r\n\r\n\t\t\t\t\t\tcamp.Treatments.forEach(function (treat) {\r\n\t\t\t\t\t\t\ttreat.Assignments.forEach(function (assign) {\r\n\t\t\t\t\t\t\t\tvar pax = paxinfoFlatten.find(function (s) { return s.PNR == assign.PNR && s.UCI == assign.UCI });\r\n\t\t\t\t\t\t\t\tif (pax) {\r\n\t\t\t\t\t\t\t\t\tassign.SeatNo = pax.SeatNo;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t// else {\r\n\t\t\t\t\t\t\t\t// \tassign.Status = 5;\r\n\t\t\t\t\t\t\t\t// \tassign.AutoSet = true;\r\n\t\t\t\t\t\t\t\t// \tassign.StatusStr = '5';\r\n\t\t\t\t\t\t\t\t// \tassign.Comments = null;\r\n\t\t\t\t\t\t\t\t// \tassign.Rate = 0;\r\n\t\t\t\t\t\t\t\t// }\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\tfunction giftStatusList() {\r\n\t\t\treturn [\r\n\t\t\t\t{ label: \"-select one-\", value: \"0\" },\r\n\t\t\t\t{ label: \"Delivered\", value: \"1\" },\r\n\t\t\t\t{ label: \"Not delivered\", value: \"2\" },\r\n\t\t\t\t{ label: \"Damaged\", value: \"3\" },\r\n\t\t\t\t{ label: \"Not available\", value: \"4\" },\r\n\t\t\t\t{ label: \"No show\", value: \"5\" },\r\n\t\t\t\t{ label: \"No interest\", value: \"7\" }];\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Remove fligthcampaigns from the local storage\r\n\t\t * @memberof CampaignFactory\r\n\t\t */\r\n\t\tfunction clearFlightCampaignsFromStorage(flightId) {\r\n\t\t\tGenericService.remove(flightId, objType, objCallback);\r\n\t\t}\r\n\r\n\t\tfunction hasPendingFeedbacks(data) {\r\n\t\t\tvar feedbackReadyCounter = 0;\r\n\t\t\t//var data = getCampaignsByFlightId(flightId);\r\n\t\t\tif (data) {\r\n\t\t\t\tfor (let camp of data.CampaignsList) {\r\n\t\t\t\t\tfor (let treat of camp.Treatments) {\r\n\t\t\t\t\t\tfeedbackReadyCounter += treat.Assignments.filter(function (a) { return a.Status > 0 }).length;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn !(data.AssignmentsCounter == feedbackReadyCounter);\r\n\t\t}\r\n\r\n\t\tfunction syncResultFormat(result) {\r\n\t\t\tvar updateText;\r\n\t\t\tvar upClass;\r\n\t\t\tvar fetchText;\r\n\t\t\tvar fetchClass;\r\n\r\n\t\t\tif (result.UpdateAssignmentsSuccess == null) {\r\n\t\t\t\tupdateText = \"No Campaigns Feedbacks were uploaded to the server. \";\r\n\t\t\t\tupClass = \"alert-cyan\";\r\n\t\t\t} else if (result.UpdateAssignmentsSuccess == true) {\r\n\t\t\t\tupdateText = \"Campaigns Feedbacks were uploaded to the server. \";\r\n\t\t\t\tupClass = \"alert-cyan\";\r\n\t\t\t} else {\r\n\t\t\t\tupdateText = \"Campaigns Feedbacks failed to be uploaded to the server. \";\r\n\t\t\t\tupClass = \"alert-deep-orange\";\r\n\t\t\t}\r\n\r\n\t\t\tif (result.GetAssignmentsSuccess == false) {\r\n\t\t\t\tfetchText = \"Campaigns Feedbacks failed to be fetched by the server.\";\r\n\t\t\t\tfetchClass = \"alert-deep-orange\";\r\n\t\t\t} else if (result.GetAssignmentsSuccess == true && result.FlightsCampaigns.length > 0) {\r\n\t\t\t\tfetchText = \"Campaigns Feedbacks were fetched by the server.\";\r\n\t\t\t\tfetchClass = \"alert-cyan\";\r\n\t\t\t} else {\r\n\t\t\t\tfetchText = \"No Campaigns Feedbacks were fetched by the server.\";\r\n\t\t\t\tfetchClass = \"alert-cyan\";\r\n\t\t\t}\r\n\r\n\t\t\treturn {\r\n\t\t\t\tupdMessage: updateText,\r\n\t\t\t\tupdClass: upClass,\r\n\t\t\t\tftcMessage: fetchText,\r\n\t\t\t\tftcClass: fetchClass\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction flatten(arr) {\r\n\t\t\treturn arr.reduce(function (flat, toFlatten) {\r\n\t\t\t\treturn flat.concat(Array.isArray(toFlatten) ? flatten(toFlatten) : toFlatten);\r\n\t\t\t}, []);\r\n\t\t}\r\n\r\n\t\t/**\r\n * Clean Old Data\r\n * @memberof CampaignFactory\r\n * @param {Array} pendingFlightIds FlightIds with pending reports\r\n */\r\n\t\tfunction cleanOldCampaigns(pendingFlightIds) {\r\n\t\t\tvar now = moment();\r\n\t\t\tgetFlightsCampaignsFromStorage(function(campaigns){\r\n\t\t\t\tvar pendingCampaigns = campaigns.FlightsCampaigns.filter(function(item){\r\n\t\t\t\t\treturn pendingFlightIds.includes(item.FlightId);\r\n\t\t\t\t});\r\n\t\t\t\t// keep only the campaigns with pending reports\r\n\t\t\t\tsetFlightCampaignsToStorage(pendingCampaigns);\t\t\t\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n})();","(function() {\r\n\r\n'use strict';\r\n \r\na3_cabin_reports.filter('bytes', bytes);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc filter\r\n * @name bytes\r\n * @description \r\n * Transform Bytes to 'kB', 'MB', 'GB', 'TB', 'PB'\r\n * @ngInject\r\n */ \r\nfunction bytes() {\r\n\t\treturn function(bytes, precision) {\r\n\t\t\tif (isNaN(parseFloat(bytes)) || !isFinite(bytes)) return '-';\r\n\t\t\tif (typeof precision === 'undefined') precision = 1;\r\n\t\t\tvar units = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],\r\n\t\t\t\tnumber = Math.floor(Math.log(bytes) / Math.log(1024));\r\n\t\t\treturn (bytes / Math.pow(1024, Math.floor(number))).toFixed(precision) + ' ' + units[number];\r\n\t\t}\r\n\t}\r\n\r\n \r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('DataCleanerFactory', DataCleanerFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name DataCleanerFactory\r\n * @description \r\n * Cleans the Data of the application\r\n * @ngInject\r\n */\r\n function DataCleanerFactory(localStorageMD5Service, IndexedDBService, GenericService) {\r\n\r\n\r\n var service = {\r\n deleteAllReports: deleteAllReports,\r\n deleteAllServerData: deleteAllServerData,\r\n deleteAllData: deleteAllData,\r\n deleteOrphanedLocalFlights: deleteOrphanedLocalFlights,\r\n deleteOrphanedLocalReports: deleteOrphanedLocalReports,\r\n deleteSynchedLocalCabinReports: deleteSynchedLocalCabinReports,\r\n deleteIndexedDB: deleteIndexedDB,\r\n deleteOldCrewMealsRatings:deleteOldCrewMealsRatings,\r\n deleteOrphanedCustomerEvents:deleteOrphanedCustomerEvents\r\n }\r\n /**\r\n * Delete All Cabin Reports\r\n * @memberof DataCleanerFactory\r\n */\r\n function deleteAllReports() {\r\n localStorageMD5Service.remove('cabinReportLocalEdits');\r\n localStorageMD5Service.remove('cabinReportLocalEdit_TEMP');\r\n deleteOrphanedLocalFlights();\r\n };\r\n\r\n /**\r\n * Delete Basic Server data\r\n * @memberof DataCleanerFactory\r\n */\r\n function deleteAllServerData() {\r\n localStorageMD5Service.remove('flights');\r\n localStorageMD5Service.remove('reportGuids');\r\n localStorageMD5Service.remove('aircraftTypes');\r\n localStorageMD5Service.remove('cabinReportTemplateItems');\r\n localStorageMD5Service.remove('cabinReportSyncResults');\r\n localStorageMD5Service.remove('assessmentSyncResults');\r\n localStorageMD5Service.remove('waterUpliftActions');\r\n localStorageMD5Service.remove('acSupplies');\r\n localStorageMD5Service.remove('specialMealSources');\r\n localStorageMD5Service.remove('specialMealTypes');\r\n localStorageMD5Service.remove('currencies');\r\n localStorageMD5Service.remove('travelValueIncompleteReasons');\r\n localStorageMD5Service.remove('incompleteInFlightServiceListOfValues');\r\n localStorageMD5Service.remove('ccms');\r\n localStorageMD5Service.remove('scheduleChanges');\r\n localStorageMD5Service.remove('CheckIn');\r\n localStorageMD5Service.remove('flightCheckIns');\r\n\r\n localStorageMD5Service.remove('CrewAssessmentTemplate');\r\n localStorageMD5Service.remove('FAQItem');\r\n localStorageMD5Service.remove('PaxInfo');\r\n\r\n localStorageMD5Service.remove('flightEventTypes');\r\n localStorageMD5Service.remove('flightEvents');\r\n deleteOrphanedLocalFlights();\r\n };\r\n\r\n /**\r\n * Delete All Server data\r\n * @memberof DataCleanerFactory\r\n */\r\n function deleteAllData() {\r\n localStorageMD5Service.clearAll();\r\n\r\n IndexedDBService.deleteDatabase();\r\n };\r\n\r\n function deleteIndexedDB() {\r\n \r\n return IndexedDBService.deleteDatabase();\r\n }\r\n\r\n\r\n /**\r\n * Delete local flights that have no stored local reports\r\n * @memberof DataCleanerFactory\r\n */\r\n function deleteOrphanedLocalFlights() {\r\n\r\n var existingLocalFlights = localStorageMD5Service.get('localFlights');\r\n if (existingLocalFlights == null)\r\n return;\r\n\r\n var finalLocalFlights = [];\r\n\r\n var cabinReportLocalEdits = localStorageMD5Service.get('cabinReportLocalEdits');\r\n if (cabinReportLocalEdits == null)\r\n cabinReportLocalEdits = [];\r\n\r\n // check every local flight that has a saved cabin report\r\n for (var i = 0; i < existingLocalFlights.length; i++) {\r\n var hasCabinReport = false;\r\n\r\n for (var j = 0; j < cabinReportLocalEdits.length; j++) {\r\n if ((cabinReportLocalEdits[j].FlightId != null && cabinReportLocalEdits[j].FlightId == existingLocalFlights[i].FlightId) || (cabinReportLocalEdits[j].FlightAimsId != null && cabinReportLocalEdits[j].FlightAimsId == existingLocalFlights[i].FlightAimsId)) {\r\n hasCabinReport = true;\r\n break;\r\n }\r\n }\r\n // if it has a cabin report, add it to the flights to save\r\n if (hasCabinReport)\r\n finalLocalFlights.push(existingLocalFlights[i]);\r\n }\r\n // save the resulting local flights\r\n localStorageMD5Service.set('localFlights', finalLocalFlights);\r\n }\r\n\r\n /**\r\n * Delete local reports that have no stored local flights\r\n * @memberof DataCleanerFactory\r\n */\r\n function deleteOrphanedLocalReports() {\r\n var existingLocalCabinReports = localStorageMD5Service.get('cabinReportLocalEdits');\r\n var flights = localStorageMD5Service.get('flights');\r\n\r\n if (existingLocalCabinReports == null || flights == null || existingLocalCabinReports.length == 0 || flights.length == 0)\r\n return 0;\r\n\r\n var finalLocalCabinReports = [];\r\n for (var i = 0; i < existingLocalCabinReports.length; i++) {\r\n var remove = false;\r\n\r\n if (existingLocalCabinReports[i].Status == 'synched') {\r\n remove = true;\r\n if (existingLocalCabinReports[i].FlightId != null || existingLocalCabinReports[i].FlightAimsId != null) {\r\n for (var j = 0; j < flights.length; j++) {\r\n if (\r\n (existingLocalCabinReports[i].FlightId != null && existingLocalCabinReports[i].FlightId == flights[j].FlightId) || (existingLocalCabinReports[i].FlightAimsId != null && existingLocalCabinReports[i].FlightAimsId == flights[j].FlightAimsId)\r\n ) {\r\n remove = false;\r\n }\r\n }\r\n }\r\n }\r\n if (!remove)\r\n finalLocalCabinReports.push(existingLocalCabinReports[i]);\r\n }\r\n // save the resulting local reports\r\n localStorageMD5Service.set('cabinReportLocalEdits', finalLocalCabinReports);\r\n }\r\n\r\n /**\r\n * Delete Synched Local CabinReports\r\n * @memberof DataCleanerFactory\r\n */\r\n function deleteSynchedLocalCabinReports() {\r\n\r\n var existingLocalCabinReports = localStorageMD5Service.get('cabinReportLocalEdits');\r\n var flights = localStorageMD5Service.get('flights');\r\n\r\n if (existingLocalCabinReports == null || flights == null || existingLocalCabinReports.length == 0 || flights.length == 0)\r\n return 0;\r\n\r\n var finalLocalCabinReports = [];\r\n var deleted = 0;\r\n\r\n var user = localStorageMD5Service.get('user');;\r\n // check every saved cabin report\r\n for (var i = 0; i < existingLocalCabinReports.length; i++) {\r\n\r\n var remove = false;\r\n\r\n if (existingLocalCabinReports[i].Status == 'synched') {\r\n if (existingLocalCabinReports[i].FlightId != null || existingLocalCabinReports[i].FlightAimsId != null) {\r\n for (var j = 0; j < flights.length; j++) {\r\n if (\r\n (existingLocalCabinReports[i].FlightId != null && existingLocalCabinReports[i].FlightId == flights[j].FlightId) || (existingLocalCabinReports[i].FlightAimsId != null && existingLocalCabinReports[i].FlightAimsId == flights[j].FlightAimsId)\r\n ) {\r\n for (var h = 0; h < flights[j].cabinReports.length; h++) {\r\n if (flights[j].cabinReports[h].AuthorAimsId == user.aimsId) {\r\n remove = true;\r\n deleted++;\r\n }\r\n\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (!remove)\r\n finalLocalCabinReports.push(existingLocalCabinReports[i]);\r\n }\r\n\r\n // save the resulting local reports\r\n localStorageMD5Service.set('cabinReportLocalEdits', finalLocalCabinReports);\r\n\r\n return deleted;\r\n }\r\n\r\n /**\r\n * Deletes CrewMealRatings that are older than 20 days\r\n * @memberof DataCleanerFactory\r\n */\r\n function deleteOldCrewMealsRatings(){\r\n var res = GenericService.list(\"CrewMealRatings\", objCallbackRatings);\r\n var lastDate = new Date();\r\n lastDate.setDate(lastDate.getDate() - 20);\r\n var crewMealIdsFiltered = res.filter(r => new Date(r.TimeStamp) >= lastDate);\r\n GenericService.saveOne(crewMealIdsFiltered,\"CrewMealRatings\");\r\n }\r\n\r\n /**\r\n * Deletes customer events whose flight doesn't exist\r\n */\r\n function deleteOrphanedCustomerEvents(){\r\n var flights = localStorageMD5Service.get('flights');\r\n var customerEvents = localStorageMD5Service.get('CustomerEvents');\r\n var finalCustomerEvents = [];\r\n\r\n if (customerEvents && flights && flights.length > 0){\r\n customerEvents.forEach(function(event){\r\n //Search if event's flight exist\r\n if(flights.find(x => x.FlightId == event.FlightId)){\r\n finalCustomerEvents.push(event);\r\n }\r\n });\r\n\r\n //save the resulting customer events\r\n localStorageMD5Service.set('CustomerEvents', finalCustomerEvents);\r\n }\r\n }\r\n\r\n function objCallbackRatings(){\r\n this.CrewMealId = null,\r\n this.TimeStamp = null\r\n }\r\n\r\n return service;\r\n }\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.filter('fltSplit',fltSplit) \r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc filter\r\n * @name messageFilter\r\n * @description \r\n * Filters messages in order to show only the unread.\r\n * @ngInject\r\n */\r\nfunction fltSplit() {\r\n\t\treturn function(fltSplit) {\r\n var formattedFltNo = fltSplit;\r\n if(typeof fltSplit === 'string' || fltSplit instanceof String){\r\n formattedFltNo = fltSplit.replace(/(\\w{2})/, '$1 ');\r\n }\r\n\t\t\treturn formattedFltNo;\r\n\t\t};\r\n\t}\r\n })();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('GenericModalFactory',GenericModalFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name GenericModalFactory\r\n * @description \r\n * Initialize generic Modals\r\n * @ngInject\r\n */ \r\nfunction GenericModalFactory() {\r\n\t\tvar service = {\r\n\t\t\tcreateNew : createNew,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tdeleteFromList : deleteFromList,\r\n\t\t\tfromObjectList : fromObjectList\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Greate new Object based on given constructor\r\n * @memberof GenericModalFactory\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} result\r\n */\r\n\t\tfunction createNew(callback) {\r\n\t\t\tvar result = new callback();\r\n\t\t\tresult.Id = guid();\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Extend given object \r\n * @memberof GenericModalFactory\r\n * @param {object} obj The object that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} object\r\n */\r\n\t\tfunction fromObject(obj,callback) {\r\n\t\t\tif (obj == null) return null;\r\n\t\t\tvar object = new callback();\r\n\t\t\tangular.extend(object, obj);\r\n\t\t\treturn object;\r\n\t\t}\r\n\r\n /**\r\n * Delete an object from given List\r\n * @memberof GenericModalFactory\r\n * @param {object} obj The object that will be removed\r\n * @param {array} objList A list that will be modified\r\n * @returns {array} objList\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\t// find the current item in the array (if present)\r\n\t\t\tvar arrayLength = objList.length;\r\n\t\t\tvar itemIndex = -1;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (objList[i].Id == obj.Id) {\r\n\t\t\t\t\titemIndex = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t\t\r\n\t\t\tif (itemIndex >= 0)\r\n\t\t\t\tobjList.splice(itemIndex, 1);\r\n\r\n\t\t\treturn objList;\r\n\t\t}\r\n\t\t \r\n /**\r\n * Extend given object list\r\n * @memberof GenericModalFactory\r\n * @param {array} objList The list of objects that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} objList\r\n */\r\n\t\tfunction fromObjectList(objList,callback) {\r\n\t\t\tif (objList == null) return [];\r\n\r\n\t\t\tvar arrayLength = objList.length;\r\n\t\t\tvar newobjList = new Array();\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tvar obj = new callback();\r\n\t\t\t\tangular.extend(obj, objList[i]);\r\n\t\t\t\tnewobjList.push(obj);\r\n\t\t\t}\r\n\r\n\t\t\treturn newobjList;\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n \r\n \r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('GenericService',GenericService);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name GenericService\r\n * @description \r\n * Generic add, edit or remove\r\n * @ngInject\r\n */\r\nfunction GenericService(localStorageMD5Service) {\r\n\r\n\t\tvar objectType = null ;\r\n\t\tvar objectCallback = null;\r\n\t\t\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tinitiate : initiate,\r\n\t\t\tget : get,\r\n\t\t\tgetOne : getOne,\r\n\t\t\tlist : list,\r\n\t\t\tsave : save,\r\n\t\t\tsaveOne : saveOne,\r\n\t\t\tsaveAll : saveAll,\r\n\t\t\tremove : remove,\r\n\t\t\tremoveAll : removeAll,\r\n\t\t\tadd : add,\r\n\t\t\tconstructor : constructor,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tsaveByFilter : saveByFilter,\r\n\t\t\tremoveByFilter : removeByFilter\r\n\t\t};\r\n\r\n /**\r\n * initiate type and callback\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @memberof GenericService\r\n */\r\n\t\tfunction initiate(type,callback){\r\n\t\t\tobjectType = type;\r\n\t\t\tobjectCallback = callback;\r\n\t\t}\r\n\t\t\r\n /**\r\n * Get the requested object\r\n * @memberof GenericService\r\n * @param {number} id The unique identifier\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} result\r\n */\r\n\t\tfunction get(id,type,callback){\r\n\t\t\tinitiate(type,callback);\r\n\t\t\tvar objects = list(type,callback);\r\n\t\t\tif (objects == null)\r\n\t\t\t\treturn null;\r\n\t\t\r\n\t\t\tvar result = null;\r\n\t\t\tvar arrayLength = objects.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (objects[i].GetId() == id) {\r\n\t\t\t\t\tresult = objects[i];\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Get all the objects\r\n * @memberof GenericService\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {array} objectList\r\n */\r\n\t\tfunction list(type,callback){\r\n\t\t\tinitiate(type,callback);\r\n\t\t\tvar objects = localStorageMD5Service.get(objectType);\r\n\t\t\treturn fromObjectList(objects,callback);\r\n\t\t}\r\n\r\n /**\r\n * Get the unique object of this storage\r\n * @memberof GenericService\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} result\r\n */\r\n\t\tfunction getOne(type,callback){\r\n\t\t\tinitiate(type,callback);\r\n\t\t\tvar object = localStorageMD5Service.get(objectType);\r\n\t\t\treturn fromObject(object,callback);\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Save the unique object of this storage\r\n * @memberof GenericService\r\n * @param {object} obj The object to save\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\\\r\n */\r\n\t\tfunction saveOne(obj,type,callback){\r\n\t\t\tlocalStorageMD5Service.set(type,obj);\r\n\t\t}\r\n\r\n /**\r\n * update the object\r\n * @memberof GenericService\r\n * @param {object} object The object to save\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\\\r\n */\r\n\t\tfunction save(object,type,callback){\r\n\t\t\tinitiate(type,callback)\r\n\t\t\tvar objects = list(type,callback);\r\n\t\t\tvar updatedobject = fromObject(object,callback);\r\n\t\t\tvar arrayLength = objects.length;\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (objects[i].GetId() == updatedobject.GetId())\t{\r\n\t\t\t\t\tobjects[i] = updatedobject;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\r\n\t\t\tsaveAll(objects,type,callback);\r\n\t\t}\r\n\t\t\r\n /**\r\n * Save the objects \r\n * @memberof GenericService\r\n * @param {array} objects The objects to save\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\\\r\n */\r\n\t\tfunction saveAll(objects,type,callback){\r\n\t\t\tinitiate(type,callback);\r\n\t\t\tlocalStorageMD5Service.set(objectType,objects);\r\n\t\t}\r\n\r\n /**\r\n * remove the object based on its unique identifier\r\n * @memberof GenericService\r\n * @param {number} Id The unique identifier\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n */\r\n\t\tfunction remove(Id,type,callback){\r\n\t\t\tinitiate(type,callback);\r\n\t\t\tvar objects = list(type,callback);\r\n\t\t\tvar newObjects = [];\r\n\t\t\tvar arrayLength = objects.length;\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (objects[i].GetId() != Id) {\r\n\t\t\t\t\tnewObjects.push(objects[i])\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\r\n\t\t\tsaveAll(newObjects,type,callback);\r\n\t\t}\r\n\r\n /**\r\n * remove all the objects\r\n * @memberof GenericService\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n */\r\n\t\tfunction removeAll(type,callback){\r\n\t\t\tinitiate(type,callback);\r\n\t\t\tlocalStorageMD5Service.remove(objectType);\r\n\t\t}\r\n\t\t\r\n /**\r\n * add the object\r\n * @memberof GenericService\r\n * @param {object} object The object to save\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n */\r\n\t\tfunction add(obj,type,callback){\r\n\t\t\tvar objects = list(type,callback);\r\n\t\t\tobjects.push(obj);\r\n\t\t\tsaveAll(objects,type,callback);\r\n\t\t}\r\n\t\t\r\n /**\r\n * Create a new object\r\n * @memberof GenericService\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} object\r\n */\r\n\t\tfunction constructor(callback){\r\n\t\t\tvar object = new callback();\r\n\t\t\treturn object;\r\n\t\t}\r\n\t\t\r\n /**\r\n * Extend given object \r\n * @memberof GenericService\r\n * @param {object} obj The object that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} object\r\n */\r\n\t\tfunction fromObject(obj,callback){\r\n\t\t\tif (obj==null) return null;\r\n\t\t\tvar object = new callback();\r\n\t\t\tangular.extend(object, obj);\r\n\t\t\treturn object;\r\n\t\t};\r\n\t\t\r\n /**\r\n * Extend given object list\r\n * @memberof GenericService\r\n * @param {array} objList The list of objects that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} objList\r\n */\r\n\t\tfunction fromObjectList(objList,callback) {\r\n\t\t\tif (objList==null)\r\n\t\t\t\treturn [];\r\n\t\t\t\r\n\t\t\tvar arrayLength = objList.length;\r\n\t\t\tvar objects = new Array();\r\n\t\t\t\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tobjects.push(fromObject(objList[i],callback));\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\treturn objects;\r\n\t\t};\r\n\r\n\t\t/**\r\n\t\t * Update object in local storage - Search it by filters\r\n\t\t * @param {object} object The objects to save\r\n\t\t * @param {array} filters Array of property-value pairs to act as ids \r\n\t\t * @param {string} type A string which identifies the local storage name\r\n\t\t * @param {function} callback A callback function that behaves as a constructor\r\n\t\t */\r\n\t\tfunction saveByFilter(object, filters, type, callback) {\r\n\t\t\tinitiate(type,callback)\r\n\t\t\tvar objects = list(type,callback);\r\n\t\t\tvar updatedobject = fromObject(object,callback);\r\n\t\t\tvar arrayLength = objects.length;\r\n\r\n\t\t\tfor (var j = 0; j < arrayLength; j++) {\r\n\t\t\t\tvar retVal = true;\r\n\t\t\t\tvar storageObject = objects[j];\r\n\t\t\t\tfor(var i = 0; i < filters.length; i++){\r\n\t\t\t\t\tif(storageObject[filters[i][0]] != filters[i][1]){\r\n\t\t\t\t\t\tretVal = false;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif(retVal){\r\n\t\t\t\t\tobjects[j] = updatedobject;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tsaveAll(objects,type,callback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Remove object from local strage - Search it by filters\r\n\t\t * @param {array} filters Array of property-value pairs to act as ids \r\n\t\t * @param {string} type A string which identifies the local storage name\r\n\t\t * @param {function} callback A callback function that behaves as a constructor\r\n\t\t */\r\n\t\tfunction removeByFilter(filters, type, callback) {\r\n\t\t\tinitiate(type,callback)\r\n\t\t\tvar objects = list(type,callback);\r\n\t\t\tvar newObjects = [];\r\n\t\t\tvar arrayLength = objects.length;\r\n\r\n\t\t\tfor (var j = 0; j < arrayLength; j++) {\r\n\t\t\t\tvar storageObject = objects[j];\r\n\t\t\t\tfor(var i = 0; i < filters.length; i++){\r\n\t\t\t\t\tif(storageObject[filters[i][0]] != filters[i][1]){\r\n\t\t\t\t\t\tnewObjects.push(storageObject)\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tsaveAll(newObjects,type,callback);\r\n\t\t}\r\n\r\n\treturn service;\r\n\t}\r\n \r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('GenericValuesFactory', GenericValuesFactory);\r\n\t\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name GenericValuesFactory\r\n * @description \r\n * Generic add, edit or remove for list of values\r\n * @ngInject\r\n */ \r\nfunction GenericValuesFactory(localStorageMD5Service) {\r\n\t\t \r\n\t\tvar service = {\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tobjList : objList,\r\n\t\t\tgetValuesFromStorage : getValuesFromStorage,\r\n\t\t\tsetValuesToStorage : setValuesToStorage,\r\n\t\t\tclearValuesFromStorage : clearValuesFromStorage,\r\n\t\t\tgetValuesFromStorageAsStrings : getValuesFromStorageAsStrings\r\n\t\t}\r\n\r\n /**\r\n * Extend given object \r\n * @memberof GenericValuesFactory\r\n * @param {object} obj The object that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} object\r\n */\r\n\t\tfunction fromObject(obj,callback) {\r\n\t\t\tif (obj == null) return null;\r\n\t\t\tvar newObj = new callback();\r\n\t\t\tnewObj.Code = obj;\r\n\t\t\treturn newObj;\r\n\t\t};\r\n\r\n \r\n /**\r\n * Extend given object list\r\n * @memberof GenericValuesFactory\r\n * @param {array} objList The list of objects that will be extended\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {object} objList\r\n */\r\n\t\tfunction fromObjectList(objList,callback) {\r\n\t\t\tif (objList == null) return null;\r\n\r\n\t\t\tvar arrayLength = objList.length;\r\n\t\t\tvar newObjList = [];\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tvar newObj = new callback();\r\n\t\t\t\tnewObj.Code = objList[i];\r\n\t\t\t\tnewObjList.push(newObj);\r\n\t\t\t}\r\n\r\n\t\t\treturn newObjList;\r\n\t\t};\r\n\r\n /**\r\n * Get all the object's Code from given list\r\n * @memberof GenericValuesFactory\r\n * @param {array} objectList An object list\r\n * @returns {array} objectList\r\n */\r\n\t\tfunction objList(objList) {\r\n\t\t\tif (objList == null) return [];\r\n\r\n\t\t\tvar arrayLength = objList.length;\r\n\t\t\tvar newObjList = [];\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tnewObjList.push(objList[i].Code);\r\n\t\t\t}\r\n\r\n\t\t\treturn newObjList;\r\n\t\t};\r\n\r\n \r\n /**\r\n * Get all the objects\r\n * @memberof GenericValuesFactory\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {array} objectList\r\n */\r\n\t\tfunction getValuesFromStorage(callback,type) {\r\n\t\t\tvar objects = localStorageMD5Service.get(type);\r\n\t\t\treturn fromObjectList(objects,callback);\r\n\t\t}\r\n\r\n \r\n /**\r\n * Set all the objects\r\n * @memberof GenericValuesFactory\r\n * @param {array} objects A list of objects.\r\n * @param {string} type A string which identifies the local storage name\r\n */\r\n\t\tfunction setValuesToStorage(objects,type) {\r\n\t\t\tlocalStorageMD5Service.set(type, objects);\r\n\t\t}\r\n\r\n /**\r\n * Remove all the objects\r\n * @memberof GenericValuesFactory\r\n * @param {string} type A string which identifies the local storage name\r\n */\r\n\t\tfunction clearValuesFromStorage(type) {\r\n\t\t\tlocalStorageMD5Service.remove(type);\r\n\t\t}\r\n\t\t \r\n /**\r\n * Get all the objects codes from local storage\r\n * @memberof GenericValuesFactory\r\n * @param {string} type A string which identifies the local storage name\r\n * @param {function} callback A callback function that behaves as a constructor\r\n * @returns {array} objectList\r\n */\r\n\t\tfunction getValuesFromStorageAsStrings(callback,type) {\r\n\t\t\tvar result = [];\r\n\t\t\tvar objs = getValuesFromStorage(callback,type);\r\n\t\t\tif (objs != null || objs != undefined) {\r\n\t\t\t\tfor (var i = 0; i < objs.length; i++) {\r\n\t\t\t\t\tresult.push(objs[i].Code);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n \r\n})();\r\n","(function () {\r\n 'use strict';\r\n a3_cabin_reports.factory('IndexedDBService', IndexedDBService);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name IndexedDBService\r\n * @description \r\n * Generic add, edit or remove for IndexedDB\r\n * @ngInject\r\n */\r\n function IndexedDBService($q, LogService) {\r\n var idbSupported = (\"indexedDB\" in window);\r\n if (!idbSupported) {\r\n LogService.debug(\"No IndexedDb is supported for this browser's version\");\r\n }\r\n \r\n\r\n \r\n return {\r\n /**\r\n * initiate or update indexedDB storage\r\n * @memberof IndexedDBService\r\n * @returns {object} promise\r\n */\r\n init: function () {\r\n var deferred = $q.defer();\r\n var request = indexedDB.open(\"a3.cabin.reports\", 10);\r\n\r\n request.onupgradeneeded = function (e) {\r\n // The database did not previously exist, so create object stores and indexes.\r\n var db = request.result;\r\n if (e.oldVersion < 1) {\r\n var gameStore = db.createObjectStore(\"Memos\", {\r\n keyPath: \"Id\"\r\n });\r\n gameStore.createIndex(\"id_idx\", \"Id\", {\r\n unique: true\r\n });\r\n }\r\n if (e.oldVersion < 2) {\r\n var gameStore1 = db.createObjectStore(\"MemoImages\", {\r\n keyPath: \"imageId\"\r\n });\r\n gameStore1.createIndex(\"id_idx\", \"imageId\", {\r\n unique: true\r\n });\r\n gameStore1.createIndex(\"memoId\", \"memoId\", {\r\n unique: false\r\n });\r\n }\r\n if (e.oldVersion < 5 && !db.objectStoreNames.contains('PaxInfo')) {\r\n \r\n var gameStore2 = db.createObjectStore(\"PaxInfo\", {\r\n keyPath: \"FlightId\"\r\n });\r\n gameStore2.createIndex(\"id_idx\", \"FlightId\", {\r\n unique: true\r\n });\r\n }\r\n if (e.oldVersion <= 6 && !db.objectStoreNames.contains('Reports')) {\r\n \r\n var gameStore3 = db.createObjectStore(\"Reports\", {\r\n keyPath: \"FlightId\"\r\n });\r\n gameStore3.createIndex(\"id_idx\", \"FlightId\", {\r\n unique: true\r\n });\r\n }\r\n if (e.oldVersion <= 7 && !db.objectStoreNames.contains('Courses')) {\r\n var gameStore3 = db.createObjectStore(\"Courses\", {\r\n keyPath: \"Id\"\r\n });\r\n gameStore3.createIndex(\"id_idx\", \"Id\", {\r\n unique: true\r\n });\r\n \r\n var store4 = db.createObjectStore(\"TrainingSessions\", {\r\n keyPath: ['day', 'courseId','dutyId']\r\n });\r\n \r\n store4.createIndex(\"id_idx\", ['day', 'courseId','dutyId'], {\r\n unique: true\r\n });\r\n \r\n store4.createIndex(\"day_idx\", \"day\", {\r\n unique: false\r\n });\r\n \r\n store4.createIndex(\"courseId_idx\", \"courseId\", {\r\n unique: false\r\n });\r\n }\r\n if (e.oldVersion <= 8 && !db.objectStoreNames.contains('FlightSessions')) {\r\n \r\n var store = db.createObjectStore(\"FlightSessions\", {\r\n keyPath: ['day', 'courseId','dutyNo', 'dutyDay']\r\n });\r\n \r\n\r\n store.createIndex(\"id_idx\", ['day', 'courseId', 'dutyNo', 'dutyDay'], {\r\n unique: true\r\n });\r\n \r\n store.createIndex(\"day_idx\", \"day\", {\r\n unique: false\r\n });\r\n \r\n store.createIndex(\"courseId_idx\", \"courseId\", {\r\n unique: false\r\n });\r\n }\r\n if (e.oldVersion <= 9 && !db.objectStoreNames.contains('ToolkitItems')) {\r\n \r\n var gameStore2 = db.createObjectStore(\"ToolkitItems\", {\r\n keyPath: \"Id\"\r\n });\r\n gameStore2.createIndex(\"id_idx\", \"Id\", {\r\n unique: true\r\n });\r\n }\r\n if (e.oldVersion <= 10 && !db.objectStoreNames.contains('PassengerMealServices')) {\r\n \r\n var gameStore = db.createObjectStore(\"PassengerMealServices\", {\r\n keyPath: \"Id\"\r\n });\r\n gameStore.createIndex(\"id_idx\", \"Id\", {\r\n unique: true\r\n });\r\n }\r\n };\r\n\r\n request.onsuccess = function () {\r\n deferred.resolve(request.result);\r\n };\r\n\r\n request.onerror = function () {\r\n LogService.error(request.error);\r\n deferred.reject(request.error);\r\n };\r\n\r\n return deferred.promise;\r\n },\r\n\r\n deleteDatabase: function (callback) {\r\n var deferred = $q.defer();\r\n var request = indexedDB.deleteDatabase(\"a3.cabin.reports\");\r\n \r\n \r\n request.onsuccess = function(){\r\n deferred.resolve();\r\n }\r\n \r\n request.onerror = function (ex) {\r\n deferred.reject(ex);\r\n };\r\n \r\n request.onabort = function (ex) {\r\n deferred.reject(ex);\r\n };\r\n \r\n return deferred.promise;\r\n \r\n },\r\n info: function(storeName) {\r\n var deferred = $q.defer();\r\n\r\n var info = function (db) {\r\n var tx = db.transaction([storeName], \"readonly\");\r\n var store = tx.objectStore(storeName);\r\n\r\n store.indexNames;\r\n store.keyPath;\r\n \r\n var indexes = \"No indexes Found\"\r\n if (store.indexNames && store.indexNames.length>0){\r\n indexes = \"Indexes :: \"\r\n for (var i = 0; i < store.indexNames.length; i++) {\r\n if(i x.length>0);\r\n \r\n //FOR FUTURE: Add Dynamic fields for search\r\n return itemArray.filter(x => searchWords.some(y => x.Title.toLowerCase().includes(y)) ||\r\n searchWords.some(y => x.Description.toLowerCase().includes(y)) ||\r\n searchWords.some(y => x.Comments && x.Comments.toLowerCase().includes(y)) ||\r\n searchWords.some(y => x.Tags.some(t => t.toLowerCase().includes(y)))); \r\n }\r\n }\r\n })();\r\n ","(function() {\r\n 'use strict';\r\na3_cabin_reports.factory('SettingsMain', SettingsMain);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SettingsMain\r\n * @description \r\n * Generic add, edit or remove\r\n * @ngInject\r\n */\r\nfunction SettingsMain($log, localStorageMD5Service, FlightFactory) {\r\n\r\n /**\r\n * Initialize the PageMainSettings\r\n * @memberof SettingsMain\r\n */\r\n\t\tfunction PageMainSettings() {\r\n\t\t\tthis.EditingPage = null;\r\n\t\t\tthis.IsAssessmentEnabled = null;\r\n this.calendarViewStyle = null;\r\n this.selectedDate = null;\r\n\t\t}\r\n\t\t\t\r\n\t\tvar service = {\r\n\t\t\tgetSettings : getSettings,\r\n\t\t\tsetSettings : setSettings,\r\n\t\t\tgetEditingPage : getEditingPage,\r\n\t\t\tsetEditingPage : setEditingPage,\r\n\t\t\tgetIsAssessmentEnabled : getIsAssessmentEnabled,\r\n\t\t\tsetIsAssessmentEnabled : setIsAssessmentEnabled,\r\n setCalendarViewStyle : setCalendarViewStyle,\r\n getCalendarViewStyle : getCalendarViewStyle,\r\n getCalendarSelectedDate : getCalendarSelectedDate,\r\n setCalendarSelectedDate : setCalendarSelectedDate\r\n\t\t}\r\n\t\t\r\n //factory functions\r\n /**\r\n * Get Application Settings\r\n * @memberof SettingsMain\r\n * @returns {object} settings \r\n */\r\n\t\tfunction getSettings() {\r\n\t\t\tvar settings = new PageMainSettings();\r\n\t\t\tvar settingsStored = localStorageMD5Service.get('settingsMain');\r\n\t\t\tif (settingsStored) {\r\n\t\t\t\tif (settingsStored.EditingPage)\r\n\t\t\t\t\tsettings.EditingPage = settingsStored.EditingPage;\r\n\t\t\t\t\r\n\r\n\t\t\t\tsettings.IsAssessmentEnabled = settingsStored.IsAssessmentEnabled;\r\n settings.calendarViewStyle = settingsStored.calendarViewStyle;\r\n settings.selectedDate = settingsStored.selectedDate;\r\n\t\t\t}\r\n\t\t\treturn settings;\r\n\t\t}\r\n\t \r\n\t /**\r\n * Set Application Settings\r\n * @param {object} settings\r\n * @memberof SettingsMain\r\n */\r\n\t\tfunction setSettings(settings) {\r\n\t\t\tlocalStorageMD5Service.set('settingsMain', settings);\r\n\t\t}\r\n\r\n /**\r\n * Get editing page\r\n * @memberof SettingsMain\r\n * @returns {string} EditingPage\r\n */\r\n\t\tfunction getEditingPage() {\r\n\t\t\tvar settings = getSettings();\r\n\t\t\treturn settings.EditingPage;\r\n\t\t}\r\n \r\n /**\r\n * Set editing page\r\n * @param {string} value\r\n * @memberof SettingsMain\r\n */\r\n\t\tfunction setEditingPage(value) {\r\n\t\t\tvar settings = getSettings();\r\n\t\t\tsettings.EditingPage = value;\r\n\t\t\tsetSettings(settings);\r\n\t\t}\r\n\r\n /**\r\n * Get if assessment is enabled\r\n * @memberof SettingsMain\r\n * @returns {boolean} isEnabled\r\n */\r\n\t\tfunction getIsAssessmentEnabled() {\r\n\t\t\tvar settings = getSettings();\r\n var isEnabled = settings.IsAssessmentEnabled;\r\n if(isEnabled){\r\n var flights = FlightFactory.getFlightsFromStorage();\r\n if (flights){\r\n for(var i=0;i {\r\n var date = moment(x.Date)\r\n if( now.diff(date, 'days') < 2){\r\n latestTimeLogs.push(x);\r\n }\r\n });\r\n \r\n setTimeLogsToStorage(latestTimeLogs);\r\n }\r\n \r\n\r\n\t\treturn service;\r\n\t}\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.service(\"UpdateService\", UpdateService);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc service\r\n * @name UpdateService\r\n * @description \r\n * Update functionality\r\n * @ngInject\r\n */\r\nfunction UpdateService(SyncLogFactory) {\r\n /**\r\n * Version patcher\r\n * @memberof UpdateService\r\n * @returns {string} NeedsSync \r\n */\r\n\t\tfunction patcher(version) {\r\n\t\t\tvar NeedsSync = false;\r\n\t\t\tif (version == \"1.0\") {\r\n\t\t\t\tSyncLogFactory.updateSyncVersion(\"1.1\")\r\n\t\t\t\t\t//patching to next version\r\n\t\t\t\tpatcher(\"1.1\");\r\n\t\t\t\tNeedsSync = true;\r\n\t\t\t} else if (version == \"1.1\") {\r\n\t\t\t\tSyncLogFactory.updateSyncVersion(\"1.2\")\r\n\t\t\t\t\t//patching to next version\r\n\t\t\t\t\t//patcher(\"1.2\");\r\n\t\t\t\tNeedsSync = true;\r\n\t\t\t}\r\n\r\n\t\t\treturn NeedsSync;\r\n\r\n\t\t}\r\n\t\treturn {\r\n /**\r\n * updates application \r\n * @memberof UpdateService\r\n * @returns {string} NeedsSync \r\n */\r\n\t\t\tupdater: function() {\r\n\t\t\t\tvar synclog = SyncLogFactory.getSyncLog();\r\n\t\t\t\tif (synclog == undefined || synclog == null) {\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t} else if (synclog.isUpdated) {\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvar NeedsSync = patcher(synclog.version);\r\n\t\t\t\t\treturn NeedsSync;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n \r\n})();\r\n","// create guid\r\nvar guid = (function() {\r\n\tfunction s4() {\r\n\t\treturn Math.floor((1 + Math.random()) * 0x10000)\r\n\t\t\t.toString(16)\r\n\t\t\t.substring(1);\r\n\t}\r\n\treturn function() {\r\n\t\treturn s4() + s4() + '-' + s4() + '-' + s4() + '-' +\r\n\t\t\ts4() + '-' + s4() + s4() + s4();\r\n\t};\r\n})();\r\n\r\n// generic sort function\r\nvar sort_by = function(field, reverse, primer) {\r\n\tvar key = function(x) {\r\n\t\treturn primer ? primer(x[field]) : x[field]\r\n\t};\r\n\r\n\treturn function(a, b) {\r\n\t\tvar A = key(a),\r\n\t\t\tB = key(b);\r\n\t\treturn ((A < B) ? -1 : ((A > B) ? 1 : 0)) * [-1, 1][+!!reverse];\r\n\t}\r\n}\r\n\r\n//used to adjust textarea to fit their content\r\nvar autoAdjustTextarea = function(element) {\r\n\ttry {\r\n\t\tif (element) {\r\n\t\t\t//element appears to have 0 scrollHeight when hidden (parent is hidden etc)\r\n\t\t\tif (element.scrollHeight > 0) {\r\n\t\t\t\telement.style.overflow = 'hidden';\r\n\t\t\t\telement.style.height = 0;\r\n\t\t\t\tif (element.scrollHeight > 40) {\r\n\t\t\t\t\telement.style.height = element.scrollHeight + 'px';\r\n\t\t\t\t} else {\r\n\t\t\t\t\telement.style.height = 40 + 'px';\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t} catch (e) {}\r\n};","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('basicFooter', basicFooter);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name basicFooter\r\n * @restrict E\r\n * @description\r\n * Implementation of basicFooter (appears in groundDuty-info view)\r\n *\r\n * Initialize a basic Footer Template and its Navigation Functionality\r\n * Used in groundDuty and crewRoute view\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function basicFooter($location, SettingsMain, UserFactory, DataCleanerFactory) {\r\n /**\r\n * Initialize basicFooter and events\r\n * @memberof basicFooter\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attrs attribute of this element\r\n */\r\n function link(scope, element, attrs) {\r\n if (scope.groundDuty || scope.crewRoute) {\r\n var state = scope.state;\r\n var user = UserFactory.getUser();\r\n var delay = 60000;\r\n\r\n /**\r\n * Open a modal from which u can Logout from the application\r\n * @memberof groundFooter \r\n */\r\n function logout() {\r\n var isSecure = UserFactory.isSecure()\r\n bootbox.dialog({\r\n message: (isSecure ?\r\n \"Due to the fact that you are working over a public computer, all stored data will be deleted on logout!

\" :\r\n \"You will be able to login again into the same account, even if there is no internet access.

\") +\r\n \"Please confirm that you wish to log out.\",\r\n title: \"User Logout\",\r\n buttons: {\r\n cancel: {\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function () {}\r\n },\r\n logout: {\r\n label: \"Logout\",\r\n className: \"btn-warning\",\r\n callback: function () {\r\n UserFactory.clearActiveUser();\r\n if (isSecure) DataCleanerFactory.deleteAllData();\r\n\r\n UserFactory.azSignOut();\r\n \r\n location.reload(true);\r\n // need to reload, in order for the\r\n // browser to check the cache.manifest\r\n // and discover any changes\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Navigate to Calendar View\r\n * @memberof groundFooter \r\n */\r\n function gotoCalendar() {\r\n // handleIfReport(state, flightId, report);\r\n\r\n SettingsMain.setEditingPage(null);\r\n // go to dashboard\r\n $location.path(\"/\");\r\n }\r\n /**\r\n * Navigate to Bucket Calendar View\r\n * @memberof groundFooter \r\n */\r\n function gotoBucketCalendar() {\r\n SettingsMain.setEditingPage(null);\r\n $location.path('/bucket');\r\n }\r\n /**\r\n * Navigate to FAQs View\r\n * @memberof groundFooter \r\n */\r\n function gotoFAQs() {\r\n SettingsMain.setEditingPage(null);\r\n $location.path('/faqs');\r\n }\r\n\r\n /**\r\n\t\t\t * Navigate to Roster Requests View\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t */\r\n function gotoRequests() {\r\n SettingsMain.setEditingPage(null);\r\n\t\t\t\t $location.path(\"/rosterRequests\");\r\n\t\t\t }\r\n\r\n /**\r\n * Navigate to Messages View\r\n * @memberof groundFooter \r\n */\r\n function gotoMessageLibrary() {\r\n $location.path('/messages');\r\n }\r\n\r\n /**\r\n * Navigate to Meal Library View\r\n * @memberof groundFooter \r\n */\r\n function gotoMealLibrary() {\r\n $location.path('/mealLibrary');\r\n }\r\n\r\n scope.gotoMessageLibrary = gotoMessageLibrary;\r\n scope.gotoFAQs = gotoFAQs;\r\n scope.gotoRequests = gotoRequests;\r\n scope.gotoBucketCalendar = gotoBucketCalendar;\r\n scope.gotoCalendar = gotoCalendar;\r\n scope.gotoMealLibrary = gotoMealLibrary;\r\n scope.logout = logout;\r\n\r\n }\r\n }\r\n\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: true,\r\n templateUrl: \"views/Main/basic-footer.tpl.html\",\r\n scope: false,\r\n link: link\r\n }\r\n\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('CheckInFactory', CheckInFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CheckInFactory\r\n * @description \r\n * Get list, Update list & Acknowledge schedule changes\r\n * @ngInject\r\n */\r\n function CheckInFactory(GenericService, $http, apiUrl, LogService) {\r\n /**\r\n * Initialize the ScheduleChanges\r\n * @memberof CheckInFactory\r\n */\r\n function CheckIn() {\r\n\r\n }\r\n\r\n var objType = 'CheckIn';\r\n var objCallback = CheckIn;\r\n\r\n var response = {\r\n success: false,\r\n message: '',\r\n checkInInfo: null\r\n };\r\n\r\n var service = {\r\n setCheckInInfoToStorage: setCheckInInfoToStorage,\r\n getCheckInInfoFromStorage: getCheckInInfoFromStorage,\r\n checkIn: checkIn,\r\n saveCheckInDelay: saveCheckInDelay\r\n };\r\n\r\n /**\r\n * Save check in info\r\n * @param {array} checkInInfo \r\n */\r\n function setCheckInInfoToStorage(checkInInfo) {\r\n if (checkInInfo == undefined || checkInInfo == null) {\r\n GenericService.removeAll(objType);\r\n }\r\n else {\r\n GenericService.saveOne(checkInInfo, objType, objCallback);\r\n }\r\n }\r\n\r\n /**\r\n * Get check in info\r\n */\r\n function getCheckInInfoFromStorage() {\r\n return GenericService.getOne(objType, objCallback);;\r\n }\r\n\r\n\r\n /**\r\n * Check In\r\n * @returns {promise} response\r\n */\r\n function checkIn(confirmed) {\r\n return $http.get(apiUrl + '/CrewCheckIn/CheckIn?confirmed=' + confirmed, { 'Content-Type': 'application/json' })\r\n .then(res => updateCheckInCallBack(res))\r\n .catch(res => checkInFailedCallBack(res));\r\n }\r\n\r\n /**\r\n * Update Schedule changes dates\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} response\r\n */\r\n function updateCheckInCallBack(res) {\r\n response.success = res.data.success;\r\n if (res.data.success) {\r\n //update local storage\r\n setCheckInInfoToStorage(res.data.data);\r\n response.checkInInfo = res.data.data;\r\n if (response.checkInInfo && response.checkInInfo.Confirmed && response.checkInInfo.ErrorExplanation === \"\") {\r\n response.message = \"Success! Check In Confirmed.\";\r\n } else if (response.checkInInfo && !response.checkInInfo.Confirmed && response.checkInInfo.ErrorExplanation === \"\") {\r\n response.message = \"Ready for Check In.\";\r\n } else if (response.checkInInfo) {\r\n response.message = response.checkInInfo.ErrorExplanation;\r\n } else {\r\n response.message = \"You have not pending Check In.\";\r\n }\r\n }\r\n else {\r\n response.message = res.data.errorMessage\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * The callback function upon failure on submit\r\n * @returns {object} response\r\n */\r\n function checkInFailedCallBack(res) {\r\n\r\n response.success = false;\r\n response.message = \"Oops! Something went wrong\"\r\n\r\n //TODO::Check status=500 error: returns res = {data: {…}, status: 500, config: {…}, statusText: \"Internal Server Error\", headers: ƒ}\r\n // res.data.data is null\r\n if (res.data && res.data.data) {\r\n response.checkInInfo = res.data.data;\r\n } else {\r\n //log results\r\n var responseString = JSON.stringify(res);\r\n LogService.error( 'CheckIn Failed CallBack, Response: ' + responseString);\r\n }\r\n return response;\r\n }\r\n\r\n /**\r\n * Save Check In Delay\r\n * @returns {promise} response\r\n */\r\n function saveCheckInDelay(delayMinutes) {\r\n var checkInInfo = getCheckInInfoFromStorage();\r\n checkInInfo.DelayMinutes = +delayMinutes;\r\n return $http.post(apiUrl + '/CrewCheckIn/SaveCheckInDelay', checkInInfo, { 'Content-Type': 'application/json' })\r\n .then(res => updateCheckInDelayCallBack(res))\r\n .catch(res => checkInFailedCallBack(res));\r\n }\r\n function updateCheckInDelayCallBack(res) {\r\n response.success = res.data.success;\r\n if (res.data.success) {\r\n response.message = \"Success! Delay message was sent.\";\r\n }\r\n else {\r\n response.message = res.data.errorMessage\r\n }\r\n\r\n return response;\r\n }\r\n return service;\r\n }\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('CheckInModalCtrl', CheckInModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CheckInModalCtrl\r\n * @description \r\n * Check in Modal\r\n * @ngInject\r\n */\r\n function CheckInModalCtrl($scope, CheckInFactory, $route, $uibModalInstance) {\r\n $scope.showContent = 'actions';\r\n $scope.cancel = cancel;\r\n $scope.checkInInfo = null; \r\n $scope.CheckInAction = CheckInAction;\r\n $scope.BackToActions = BackToActions;\r\n $scope.ConfirmCheckIn = ConfirmCheckIn;\r\n $scope.SendDelayMessage = SendDelayMessage;\r\n $scope.GetCheckInInfoFromServer = GetCheckInInfoFromServer;\r\n $scope.responseObj = { success: false, message: '', checkInInfo: null };\r\n $scope.results = [];\r\n\r\n $scope.selectedDelayMinutes = 10;\r\n $scope.onMinutesChange = onMinutesChange;\r\n $scope.numberDown = numberDown;\r\n $scope.numberUp = numberUp;\r\n GetCheckInInfoFromServer();\r\n \r\n \r\n function GetCheckInInfoFromServer(){\r\n $scope.showContent = 'loading';\r\n var confirmCheckIn = false;\r\n CheckInFactory.checkIn(confirmCheckIn)\r\n .then(res => handleRefreshResponse(res))\r\n .catch(res => handleRefreshResponse(res));\r\n \r\n } \r\n function handleRefreshResponse(res) {\r\n $scope.showContent = 'actions';\r\n $scope.responseObj = res;\r\n }\r\n\r\n function CheckInAction(){\r\n $scope.showContent = 'confirm';\r\n }\r\n function BackToActions(){\r\n $scope.showContent = 'actions';\r\n }\r\n\r\n function ConfirmCheckIn(){\r\n $scope.showContent = 'loading';\r\n var confirmCheckIn = true;\r\n CheckInFactory.checkIn(confirmCheckIn)\r\n .then(res => handleSubmitResponse(res))\r\n .catch(res => handleSubmitResponse(res));\r\n \r\n }\r\n\r\n function handleSubmitResponse(res) {\r\n $scope.showContent = 'results';\r\n $scope.responseObj = res;\r\n }\r\n\r\n\r\n function onMinutesChange(minutes){\r\n $scope.selectedDelayMinutes = minutes;\r\n }\r\n\r\n\r\n function SendDelayMessage(){\r\n $scope.showContent = 'loading';\r\n CheckInFactory.saveCheckInDelay($scope.selectedDelayMinutes)\r\n .then(res => handleDelayMessageResponse(res))\r\n .catch(res => handleDelayMessageResponse(res));\r\n }\r\n\r\n function handleDelayMessageResponse(res) {\r\n $scope.showContent = 'results';\r\n $scope.responseObj.success = res.success;\r\n $scope.responseObj.message = res.message;\r\n }\r\n\r\n /**\r\n * Decrease field value by 5\r\n */\r\n function numberDown(selectedDelayMinutes){\r\n if(selectedDelayMinutes > 0){\r\n $scope.selectedDelayMinutes = selectedDelayMinutes - 5;\r\n }\r\n } \r\n\r\n /**\r\n * Increase field value by 5\r\n */\r\n function numberUp(selectedDelayMinutes){\r\n $scope.selectedDelayMinutes = selectedDelayMinutes + 5;\r\n }\r\n\r\n /**\r\n * Closes modal\r\n */\r\n function cancel() {\r\n $uibModalInstance.close('cancel');\r\n\r\n // if($scope.responseObj.success){\r\n // $route.reload();\r\n // }\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('ExpiriesFactory', ExpiriesFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ExpiriesFactory\r\n * @description \r\n * Get medical & passport expiries.\r\n * @ngInject\r\n */\r\n function ExpiriesFactory(GenericService) {\r\n\r\n var objType = 'CrewExpiries';\r\n var objCallback = CrewExpiries;\r\n\r\n\r\n /**\r\n * Initialize the ScheduleChanges\r\n * @memberof ScheduleAcknowledgeFactory\r\n */\r\n function CrewExpiries() {\r\n this.expiries = [];\r\n this.showExpiriesModal = false;\r\n }\r\n\r\n var service = {\r\n setCrewExpiriesToStorage: setCrewExpiriesToStorage,\r\n getCrewExpiriesFromStorage: getCrewExpiriesFromStorage,\r\n showExpiriesModal: showExpiriesModal,\r\n showExpiriesAlert: showExpiriesAlert,\r\n updateShowExpiriesModal: updateShowExpiriesModal,\r\n };\r\n\r\n /**\r\n * Save expiries info to storage\r\n * @param {array} objList A list of Crew Expiries\r\n */\r\n function setCrewExpiriesToStorage(objList) {\r\n if (objList != null) {\r\n var crewExpiries = { expiries: objList, showExpiriesModal: true };\r\n GenericService.saveOne(crewExpiries, objType, objCallback);\r\n }\r\n }\r\n\r\n /**\r\n * Get expiries info from storage\r\n */\r\n function getCrewExpiriesFromStorage() {\r\n return GenericService.getOne(objType, objCallback);\r\n }\r\n\r\n /**\r\n * Shows expiries modal\r\n * @memberof ExpiriesFactory\r\n * @returns {bool} returns the value of showExpiriesModal property\r\n */\r\n function showExpiriesModal() {\r\n var crewExpiries = getCrewExpiriesFromStorage();\r\n\r\n var needsReminder = false;\r\n\r\n if (crewExpiries && crewExpiries.expiries && crewExpiries.showExpiriesModal) {\r\n needsReminder = crewExpiries.expiries.some(function (item) {\r\n return (item.ExpiryTypeId == 1 || item.ExpiryTypeId == 2 || item.ExpiryTypeId == 66) && item.NeedsHardAlert;\r\n });\r\n }\r\n\r\n return needsReminder;\r\n }\r\n\r\n /**\r\n * Shows expiries alert\r\n * @memberof ExpiriesFactory\r\n * @returns {bool} returns the value of showExpiriesAlert property\r\n */\r\n function showExpiriesAlert() {\r\n var crewExpiries = getCrewExpiriesFromStorage();\r\n\r\n var needsAlert = false;\r\n\r\n if (crewExpiries && crewExpiries.expiries) {\r\n needsAlert = crewExpiries.expiries.some(function (item) {\r\n return (item.ExpiryTypeId == 1 || item.ExpiryTypeId == 2 || item.ExpiryTypeId == 66) && item.NeedsSoftAlert;\r\n });\r\n }\r\n\r\n return needsAlert;\r\n }\r\n\r\n /* Update expiries modal object to storage\r\n * @memberof ExpiriesFactory\r\n * @param {bool} canShowModal whether the modal can be displayed\r\n */\r\n function updateShowExpiriesModal(canShowModal) {\r\n\r\n var crewExpiries = getCrewExpiriesFromStorage();\r\n crewExpiries.showExpiriesModal = canShowModal;\r\n GenericService.saveOne(crewExpiries, objType, objCallback);\r\n }\r\n\r\n return service;\r\n }\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.controller('CrewCallCtrl', CrewCallCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CrewCallCtrl\r\n * @description \r\n * View confirmation warning when clicking on a crew member's telephone - Monitor call requests\r\n * @ngInject\r\n */\r\n\tfunction CrewCallCtrl($scope, $uibModalInstance, crew, flightId, groundDutyId, CrewCallFactory, UserFactory, LogCallFactory) {\r\n\r\n $scope.close = close;\r\n $scope.call = call;\r\n $scope.beforeCall = true;\r\n $scope.crewFixed = null;\r\n if(crew.id) {\r\n $scope.crewFixed = crew;\r\n }\r\n else {\r\n $scope.crewFixed = {\r\n id: crew.Id,\r\n name: crew.Name,\r\n PhoneNumber: crew.PhoneNumber\r\n }\r\n }\r\n \r\n \r\n /**\r\n * Close the modal\r\n */\r\n\t\tfunction close() {\r\n\t\t\t$uibModalInstance.close(false);\r\n\t\t}\r\n\r\n /**\r\n * Confirm Call\r\n */\r\n function call(){\r\n $scope.beforeCall = false;\r\n var user = UserFactory.getUser();\r\n\r\n var logData = {\r\n Requester : user.id,\r\n Requestee: $scope.crewFixed.id,\r\n FlightId : flightId,\r\n GroundDutyId : groundDutyId,\r\n Date : moment.utc()\r\n };\r\n\r\n if($scope.isOffline){\r\n //Offline: save audit to local storage, send later on sync\r\n LogCallFactory.saveLogCall(logData);\r\n }\r\n else{\r\n //Online : API call to save audit right now\r\n CrewCallFactory.LogCall(logData, function (responseData) { \r\n }); \r\n }\r\n }\r\n\t}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('CrewCallFactory', CrewCallFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewCallFactory\r\n * @ngInject\r\n */\r\n function CrewCallFactory(GenericService, $http, apiUrl) {\r\n function CrewCall() {\r\n\t\t\tthis.FlightId = null;\r\n this.CrewId = null;\r\n this.phoneNumber = null;\r\n\t\t}\r\n\r\n var objType ='crewCall';\r\n\t\tvar objCallback = CrewCall; \r\n\r\n var service = {\r\n getCrewCallsFromStorage : getCrewCallsFromStorage,\r\n setCrewCallsToStorage : setCrewCallsToStorage,\r\n getCrewCallFromStorage : getCrewCallFromStorage,\r\n getFlightCrewCallsFromStorage : getFlightCrewCallsFromStorage,\r\n saveCrewCall : saveCrewCall,\r\n cleanOldData : cleanOldData,\r\n LogCall: LogCall,\r\n cleanFlightCrewNumbers : cleanFlightCrewNumbers,\r\n saveFlightPhoneNumbers : saveFlightPhoneNumbers\r\n };\r\n\r\n /**\r\n * Get Crew Phone Numbers.\r\n * @memberof CrewCallFactory\r\n * @returns {Array} CrewPhoneNumbers \r\n */\r\n\t\tfunction getCrewCallsFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get Crew Phone Numbers for specified flight\r\n * @memberof CrewCallFactory\r\n * @param {number} flightId\r\n * @returns {Array} CrewPhoneNumbers \r\n */\r\n\t\tfunction getFlightCrewCallsFromStorage(flightId) {\r\n\t\t\tvar phoneNumbers = GenericService.list(objType,objCallback);\r\n return phoneNumbers.filter(x => x.FlightId == flightId);\r\n\t\t}\r\n\r\n /**\r\n * Save Crew Phone Numbers to storage\r\n * @memberof CrewCallFactory\r\n * @param {Array} CrewPhoneNumbers\r\n */\r\n\t\tfunction setCrewCallsToStorage(objList) {\r\n\t\t\tGenericService.saveAll(objList,objType);\r\n }\r\n\r\n /**\r\n * Get Crew Phone Number from storage \r\n * @memberof CrewCallFactory\r\n * @param {number} crewId\r\n * @param {number} flightId\r\n * @return {object} crew phone number\r\n */\r\n\t\tfunction getCrewCallFromStorage(crewId, flightId) {\r\n var phoneNumbers = getCrewCallsFromStorage();\r\n\r\n return phoneNumbers.find(x => x.FlightId == flightId && x.CrewId == crewId);\r\n\t\t}\r\n \r\n /**\r\n\t\t * Save a fetched crew phone number\r\n * @memberof CrewCallFactory\r\n\t\t * @param {object} crewCall \r\n\t\t */\r\n\t\tfunction saveCrewCall(crewCall){\r\n GenericService.add(crewCall, objType, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Clean ls from old flight phone numbers\r\n * @param {array} flights Synced flights\r\n */\r\n function cleanOldData(responseFlightIds){\r\n var phoneNumbers = getCrewCallsFromStorage();\r\n //Filter out phone numbers of old flights\r\n phoneNumbers = phoneNumbers.filter(x => responseFlightIds.includes(x.FlightId));\r\n \r\n var now = moment.utc();\r\n var keepingPhoneNumbers = [];\r\n phoneNumbers.forEach(function(item){\r\n\r\n //Fetch FROM\r\n //Convert from Date UTC to Moment UTC\r\n var dateSTD = new Date(item.STD).fromUTC();\r\n var std = moment(dateSTD).utc(); \r\n var minFetchTime = moment(std).add(-24, 'hours');\r\n\r\n //Fetch UNTIL\r\n //Convert from Date UTC to Moment UTC\r\n var dateSTA = new Date(item.STA).fromUTC();\r\n var sta = moment(dateSTA).utc(); \r\n var maxFetchTime = moment(sta).add(2, 'hours');\r\n \r\n var isAfter = now.isAfter(minFetchTime);\r\n var isBefore = now.isBefore(maxFetchTime);\r\n\r\n if(isAfter && isBefore){\r\n keepingPhoneNumbers.push(item);\r\n }\r\n \r\n });\r\n\r\n setCrewCallsToStorage(keepingPhoneNumbers);\r\n }\r\n\r\n /**\r\n * Log call request\r\n * @param {string} logData Requester, Requestee, FlightId\r\n * @param {function} callback \r\n * @param {function} errorCallback \r\n */\r\n function LogCall(logData, callback, errorCallback) {\r\n return $http.post(apiUrl + '/Info/LogCrewMemberCall', logData, { 'Content-Type': 'application/json' })\r\n .then(callback)\r\n .catch(errorCallback);\r\n }\r\n\r\n /**\r\n * Clean all stored phone numbers for selected flight\r\n * @param {number} flightId \r\n */\r\n function cleanFlightCrewNumbers(flightId){\r\n var phoneNumbers = getCrewCallsFromStorage();\r\n\t\t\tphoneNumbers = phoneNumbers.filter(x => x.FlightId != flightId);\r\n\t\t\tsetCrewCallsToStorage(phoneNumbers);\r\n }\r\n\r\n /**\r\n * Save any found crew phone numbers for specified flight\r\n * @param {number} flightId \r\n * @param {array} crew \r\n * @param {datetime} sta \r\n * @param {datetime} std \r\n */\r\n function saveFlightPhoneNumbers(flightId, crew, sta, std){\r\n crew.forEach(function(user){\r\n if(user.PhoneNumber){\r\n var crewPhone = {\r\n FlightId : flightId,\r\n CrewId : user.id,\r\n PhoneNumber : user.PhoneNumber,\r\n STA : sta, //sta & std values will be used during sync to check timerange eligibility (-24h sta / +2h std)\r\n STD : std\r\n };\r\n saveCrewCall(crewPhone);\r\n }\r\n });\r\n }\r\n \r\n return service;\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('FlightCheckInsFactory', FlightCheckInsFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightCheckInsFactory\r\n * @ngInject\r\n */\r\n function FlightCheckInsFactory(GenericService) {\r\n function FlightCheckIn() {\r\n\t\t\tthis.FlightId = null;\r\n this.CrewId = null;\r\n this.CheckIn = null;\r\n this.WillBeThereAt = null;\r\n\r\n\t\t}\r\n\r\n var objType ='flightCheckIns';\r\n\t\tvar objCallback = FlightCheckIn; \r\n\r\n var service = {\r\n updateFlightCrewCheckInToStorage : updateFlightCrewCheckInToStorage,\r\n getFlightCrewCheckInFromStorage : getFlightCrewCheckInFromStorage,\r\n cleanOldData: cleanOldData\r\n };\r\n\r\n /**\r\n * Get Crew Check-Ins.\r\n * @memberof CrewCallFactory\r\n * @returns {Array} CrewPhoneNumbers \r\n */\r\n\t\tfunction getCrewCheckInFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save crew checkIns to storage\r\n * @memberof CrewCallFactory\r\n * @param {Array} CrewPhoneNumbers\r\n */\r\n\t\tfunction setCrewCheckInToStorage(objList) {\r\n\t\t\tGenericService.saveAll(objList,objType);\r\n }\r\n\r\n /**\r\n * Update Crew CheckIns for specified flight\r\n * @memberof CrewCallFactory\r\n * @param {} flight duty\r\n * @returns {Array} CrewFlightCrewCheckIns \r\n */\r\n function updateFlightCrewCheckInToStorage(duty){\r\n //Get all checkIns exept current flight from storage\r\n var storedCheckIns = getCrewCheckInFromStorage();\r\n var storedCheckInsFiltered = storedCheckIns.filter(f=>f.FlightId != duty.FlightInfo.FlightId);\r\n //Get checkIns from duty and add new crew checkIns to list\r\n if(duty && duty.FlightInfo && duty.FlightInfo.crew){\r\n duty.FlightInfo.crew.forEach(function(item){\r\n storedCheckInsFiltered.push({FlightId: duty.FlightInfo.FlightId, CrewId: item.id, CheckIn: item.CheckIn, WillBeThereAt: item.WillBeThereAt});\r\n });\r\n //save checkIns\r\n setCrewCheckInToStorage(storedCheckInsFiltered);\r\n }\r\n }\r\n\r\n /**\r\n * Get Crew CheckIns for specified flight\r\n * @memberof CrewCallFactory\r\n * @param {number} flightId\r\n * @returns {Array} CrewFlightCrewCheckIns \r\n */\r\n\t\tfunction getFlightCrewCheckInFromStorage(flightId) {\r\n\t\t\tvar storedCheckIns = getCrewCheckInFromStorage();\r\n return storedCheckIns.filter(x => x.FlightId == flightId);\r\n\t\t}\r\n\r\n\r\n /**\r\n * Clean ls from old flights crew check-ins\r\n * @param {array} flights Synced flights\r\n */\r\n function cleanOldData(responseFlightIds){ \r\n var storedCheckIns = getCrewCheckInFromStorage(); \r\n //Filter out crew check-ins of old flights\r\n var previousCheckIns = storedCheckIns.filter(x => responseFlightIds.includes(x.FlightId));\r\n \r\n setCrewCheckInToStorage(previousCheckIns);\r\n }\r\n\r\n return service;\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('crewInfo', crewInfo);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name crewInfo\r\n * @restrict E\r\n * @description\r\n * Crew Table with a double row per crew member\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function crewInfo($uibModal, UserFactory, PaxInfoFactory) {\r\n function link(scope, element, attrs) {\r\n scope.user = UserFactory.getUser();\r\n scope.openPhoneConfirmation = openPhoneConfirmation;\r\n scope.showInfoRow = showInfoRow;\r\n scope.showArrivalFormat = showArrivalFormat;\r\n scope.hiddenButtonHistory = scope.aircraftroute;\r\n\r\n if (scope.type == \"flight\") {\r\n scope.crewMembers = scope.crew.filter(x => (x.position == 'CP' || x.position == \"FO\") && !x.isDHC) .sort((a, b) => {\r\n const positionOrder = ['CP', 'FO' ]; \r\n return positionOrder.indexOf(a.position) - positionOrder.indexOf(b.position);\r\n });\r\n }\r\n else if (scope.type == \"cabin\") {\r\n scope.crewMembers = scope.crew.filter(x => (x.position == 'SA' || x.position == \"FA\") && !x.isDHC);\r\n }\r\n else {\r\n scope.crewMembers = scope.crew.filter(x => x.isDHC);\r\n if(scope.crewMembers.length > 0 && !scope.hiddenButtonHistory){\r\n PaxInfoFactory.getPaxInfoList(scope.selectedflightid, function (passengerList) {\r\n if (passengerList) {\r\n scope.crewMembers.forEach(function (crewMember) {\r\n var matchedPassenger = passengerList.filter(x =>\r\n (x.IsDHC && x.Fullname.toUpperCase().includes(crewMember.name.toUpperCase()))\r\n );\r\n if (matchedPassenger && matchedPassenger.length > 0) {\r\n crewMember.seatNo = matchedPassenger[0].SeatNo;\r\n }\r\n });\r\n }\r\n });\r\n }\r\n }\r\n\r\n function openPhoneConfirmation(crew) {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/CrewInfo/dlgConfirmCrewCall.html',\r\n controller: 'CrewCallCtrl',\r\n size: 'md',\r\n resolve: {\r\n crew: function () { return crew; },\r\n flightId: function () { return scope.selectedflightid; },\r\n groundDutyId: function () { return null; }\r\n }\r\n });\r\n modalInstance.result.then(function (confirm) {\r\n\r\n });\r\n }\r\n\r\n function showInfoRow(item) { \r\n var differentUser = scope.user.aimsId != item.aimsId\r\n var phoneAvailable = item.PhoneNumber && item.PhoneNumber != '';\r\n var previousDutyAvailable = item.PreviousDuty && item.PreviousDuty.isDifferent;\r\n var phonesAvailable = scope.crew.filter(x => x.PhoneNumber && x.PhoneNumber != '').length > 0;\r\n var checkInStatusAvailable = scope.crew.filter(x => x.CheckIn || x.WillBeThereAt).length > 0;\r\n\r\n var needsAdditionalFeedback = item.needsAdditionalFeedback;\r\n\r\n return differentUser && (phoneAvailable || previousDutyAvailable || phonesAvailable || checkInStatusAvailable || needsAdditionalFeedback);\r\n \r\n }\r\n\r\n function showArrivalFormat(previousDuty) {\r\n var formatedArrival = '';\r\n var dateFormat = 'HH:mm';\r\n if (previousDuty.showArrivalDate) {\r\n dateFormat = 'dd/MM HH:mm';\r\n }\r\n\r\n if (previousDuty.ATA) {\r\n\r\n formatedArrival = '- A ' + moment(previousDuty.ATA).format(dateFormat);\r\n } else if (previousDuty.ETA) {\r\n formatedArrival = '- E ' + moment(previousDuty.ETA).format(dateFormat);\r\n } else {\r\n formatedArrival = '- S ' + moment(previousDuty.STA).format(dateFormat);\r\n }\r\n\r\n return formatedArrival;\r\n }\r\n\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/CrewInfo/crewInfo.tpl.html',\r\n scope: { crew: \"=\", type: \"=\", selectedflightid: \"=\", aircraftroute: \"=\" },\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('crewPreviousInfo', crewPreviousInfo);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name crewPreviousInfo\r\n * @restrict E\r\n * @description\r\n * Crew Table with a double row per crew member showing previous duty info\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function crewPreviousInfo($uibModal, UserFactory) {\r\n function link(scope, element, attrs) {\r\n scope.user = UserFactory.getUser();\r\n scope.filterByPreviousDuty = filterByPreviousDuty;\r\n\r\n if(scope.type==\"flight\"){\r\n scope.crewMembers = scope.crew.filter(x => (x.position =='CP' || x.position == \"FO\") && !x.isDHC );\r\n }\r\n else if(scope.type==\"cabin\"){\r\n scope.crewMembers = scope.crew.filter(x => (x.position =='SA' || x.position == \"FA\") && !x.isDHC );\r\n }\r\n else{\r\n scope.crewMembers = scope.crew.filter(x => x.isDHC );\r\n }\r\n\r\n function filterByPreviousDuty(){\r\n return function( crew ) {\r\n return crew.PreviousDuty && crew.PreviousDuty.isDifferent;\r\n };\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/CrewInfo/crewPreviousInfo.tpl.html',\r\n scope: {crew:\"=\", type:\"=\"},\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('LogCallFactory', LogCallFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name LogCallFactory\r\n * @ngInject\r\n */\r\n function LogCallFactory(GenericService, $http, apiUrl) {\r\n function LogCall() {\r\n this.Requester = null;\r\n this.Requestee = null;\r\n\t\t\tthis.FlightId = null;\r\n this.GroundDutyId = null;\r\n this.Date = null;\r\n\t\t}\r\n \r\n var objType ='logCall';\r\n\t\tvar objCallback = LogCall; \r\n\r\n var service = {\r\n getLogCallsFromStorage : getLogCallsFromStorage,\r\n cleanLogsFromStorage : cleanLogsFromStorage,\r\n saveLogCall : saveLogCall\r\n };\r\n\r\n /**\r\n * Get Offline Logged Calls.\r\n * @memberof LogCallFactory\r\n */\r\n\t\tfunction getLogCallsFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Clean local storage\r\n * @memberof CrewCallFactory\r\n */\r\n\t\tfunction cleanLogsFromStorage() {\r\n GenericService.removeAll(objType,objCallback);\r\n }\r\n\r\n\r\n /**\r\n\t\t * Save an offline call request\r\n * @memberof CrewCallFactory\r\n\t\t * @param {object} logData \r\n\t\t */\r\n\t\tfunction saveLogCall(logData){\r\n GenericService.add(logData, objType, objCallback);\r\n\t\t}\r\n\r\n return service;\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('PreviousDutyFactory', PreviousDutyFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PreviousDutyFactory\r\n * @ngInject\r\n */\r\n function PreviousDutyFactory(GenericService, $http, apiUrl) {\r\n function PreviousDuty() {\r\n\t\t\tthis.FlightId = null;\r\n this.CrewId = null;\r\n this.PreviousDuty = null;\r\n\t\t}\r\n\r\n var objType ='previousDuty';\r\n\t\tvar objCallback = PreviousDuty; \r\n\r\n var service = {\r\n getPreviousDutiesFromStorage : getPreviousDutiesFromStorage,\r\n setPreviousDutiesToStorage : setPreviousDutiesToStorage,\r\n getPreviousDutyFromStorage : getPreviousDutyFromStorage,\r\n getFlightPreviousDutiesFromStorage : getFlightPreviousDutiesFromStorage,\r\n savePreviousDuty : savePreviousDuty,\r\n cleanOldData : cleanOldData,\r\n cleanFlightPreviousDuties : cleanFlightPreviousDuties,\r\n saveFlightPreviousDuties : saveFlightPreviousDuties\r\n };\r\n\r\n /**\r\n * Get Crew Phone Numbers.\r\n * @memberof PreviousDutyFactory\r\n * @returns {Array} PreviousDuties \r\n */\r\n\t\tfunction getPreviousDutiesFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get Crew Phone Numbers for specified flight\r\n * @memberof PreviousDutyFactory\r\n * @param {number} flightId\r\n * @returns {Array} PreviousDuties \r\n */\r\n\t\tfunction getFlightPreviousDutiesFromStorage(flightId) {\r\n\t\t\tvar previousDuties = GenericService.list(objType,objCallback);\r\n return previousDuties.filter(x => x.FlightId == flightId);\r\n\t\t}\r\n\r\n /**\r\n * Save Crew Phone Numbers to storage\r\n * @memberof PreviousDutyFactory\r\n * @param {Array} PreviousDuties\r\n */\r\n\t\tfunction setPreviousDutiesToStorage(objList) {\r\n\t\t\tGenericService.saveAll(objList,objType);\r\n }\r\n\r\n /**\r\n * Get Previous Duty from storage \r\n * @memberof PreviousDutyFactory\r\n * @param {number} crewId\r\n * @param {number} flightId\r\n * @return {object} previous duty info\r\n */\r\n\t\tfunction getPreviousDutyFromStorage(crewId, flightId) {\r\n var previousDuties = getPreviousDutiesFromStorage();\r\n\r\n return previousDuties.find(x => x.FlightId == flightId && x.CrewId == crewId);\r\n\t\t}\r\n \r\n /**\r\n\t\t * Save a fetched previous duty\r\n * @memberof PreviousDutyFactory\r\n\t\t * @param {object} previousDuty \r\n\t\t */\r\n\t\tfunction savePreviousDuty(previousDuty){\r\n GenericService.add(previousDuty, objType, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Clean ls from old flight previous duties\r\n * @param {array} flights Synced flights\r\n */\r\n function cleanOldData(responseFlightIds){\r\n var previousDuties = getPreviousDutiesFromStorage();\r\n //Filter out previous duties of old flights\r\n previousDuties = previousDuties.filter(x => responseFlightIds.includes(x.FlightId));\r\n \r\n setPreviousDutiesToStorage(previousDuties);\r\n }\r\n\r\n /**\r\n * Clean all stored previous duties for selected flight\r\n * @param {number} flightId \r\n */\r\n function cleanFlightPreviousDuties(flightId){\r\n var previousDuties = getPreviousDutiesFromStorage();\r\n\t\t\tpreviousDuties = previousDuties.filter(x => x.FlightId != flightId);\r\n\t\t\tsetPreviousDutiesToStorage(previousDuties); \r\n }\r\n\r\n /**\r\n * Save previous duty info for each flight crew member that has one \r\n * @param {number} flightId \r\n * @param {array} crew \r\n */\r\n function saveFlightPreviousDuties(flightId, crew){\r\n\t\t\t\tcrew.forEach(function(user){\r\n\t\t\t\t\tif(user.PreviousDuty){\r\n\t\t\t\t\t\tvar previousDuty = {\r\n\t\t\t\t\t\t\tFlightId : flightId,\r\n\t\t\t\t\t\t\tCrewId : user.id,\r\n\t\t\t\t\t\t\tPreviousDuty : user.PreviousDuty\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t\tsavePreviousDuty(previousDuty);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n }\r\n\r\n return service;\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('CrewContactsModalCtrl', CrewContactsModalCtrl)\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CrewContactsModalCtrl\r\n * @description \r\n * Shows crew detais with contacts \r\n * @ngInject\r\n */\r\n\r\n function CrewContactsModalCtrl($scope, $timeout, $uibModalInstance, crewInfo, selectedflightid, selectedFlightNo){\r\n $scope.crew = crewInfo;\r\n $scope.selectedflightid = selectedflightid;\r\n $scope.closeCrewPanel = closeCrewPanel;\r\n $scope.selectedFlightNo = selectedFlightNo;\r\n /**\r\n * Close the modal \r\n * @memberof BucketModalCtrl\r\n */\r\n function closeCrewPanel(){\r\n $uibModalInstance.close();\r\n }\r\n\r\n \r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('CrewHotelFactory', CrewHotelFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewHotelFactory\r\n * @description \r\n * Get hotels\r\n * @ngInject\r\n */\r\n function CrewHotelFactory(GenericService, $http, apiUrl) {\r\n\r\n var objType = 'crewHotel';\r\n var objCallback = CrewHotel;\r\n\r\n var service = {\r\n getCrewHotelsFromStorage: getCrewHotelsFromStorage,\r\n setCrewHotelsToStorage: setCrewHotelsToStorage,\r\n getCrewHotelFromStorage: getCrewHotelFromStorage \r\n };\r\n\r\n /**\r\n * Initialize the CrewHotel\r\n * @memberof CrewHotelFactory\r\n */\r\n function CrewHotel() {\r\n this.AimsId = null;\r\n this.CrewName = null;\r\n this.DutyDate = null;\r\n this.Base = null;\r\n this.Airport = null;\r\n this.HotelNo = null;\r\n this.HotelName = null;\r\n this.GroundTime = null;\r\n }\r\n\r\n /**\r\n * Get Crew Hotels\r\n * @memberof CrewHotelFactory\r\n * @returns {Array} CrewHotels \r\n */\r\n function getCrewHotelsFromStorage() {\r\n return GenericService.list(objType, objCallback);\r\n }\r\n\r\n /**\r\n * Save Crew Hotels to storage\r\n * @memberof GroundDutyFactory\r\n * @param {Array} objList A list of Crew Hotels\r\n */\r\n function setCrewHotelsToStorage(objList) {\r\n GenericService.saveAll(objList, objType);\r\n }\r\n\r\n /**\r\n * Get a specific Hotel\r\n * @memberof CrewHotelFactory\r\n * @returns {object} CrewHotel\r\n */\r\n function getCrewHotelFromStorage( dutydate ) {\r\n var crewHotels = getCrewHotelsFromStorage();\r\n if (crewHotels == null)\r\n return [];\r\n var arrayLength = crewHotels.length;\r\n for (var i = 0; i < arrayLength; i++) {\r\n if (crewHotels[i].Dutydate == dutydate) {\r\n return crewHotels[i];\r\n }\r\n }\r\n }\r\n\r\n\r\n\r\n return service;\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('CrewMealFactory', CrewMealFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewMealFactory\r\n * @description \r\n * Get and Update Crew Meals \r\n * @ngInject\r\n */\r\n function CrewMealFactory(GenericService, $http, apiUrl) {\r\n\r\n var objType = 'crewMeal';\r\n var objCallback = CrewMeal;\r\n var objCallbackRatings = RatingObj;\r\n var ratingSubmitResponseObj = { success: false, message: '' }\r\n\r\n var service = {\r\n getCrewMealsFromStorage: getCrewMealsFromStorage,\r\n setCrewMealsToStorage: setCrewMealsToStorage,\r\n getCrewMealFromStorage: getCrewMealFromStorage,\r\n sendCrewMealsRatingReport: sendCrewMealsRatingReport,\r\n hasRating: hasRating,\r\n getCrewMealsDidNotEatReasons: getCrewMealsDidNotEatReasons\r\n };\r\n\r\n /**\r\n * Initialize the CrewMeal\r\n * @memberof CrewMealFactory\r\n */\r\n function CrewMeal() {\r\n this.CateringMealId = null;\r\n this.Title = null;\r\n this.Description = null;\r\n }\r\n\r\n function RatingObj() {\r\n this.CrewMealId = null,\r\n this.TimeStamp = null\r\n\r\n }\r\n\r\n\r\n /**\r\n * Get Crew Meals\r\n * @memberof CrewMealFactory\r\n * @returns {Array} CrewMeals \r\n */\r\n function getCrewMealsFromStorage() {\r\n return GenericService.list(objType, objCallback);\r\n }\r\n\r\n /**\r\n * Save Crew Meals to storage\r\n * @memberof GroundDutyFactory\r\n * @param {Array} objList A list of Crew Meals\r\n */\r\n function setCrewMealsToStorage(objList) {\r\n GenericService.saveAll(objList, objType);\r\n }\r\n\r\n /**\r\n * Get a specific Crew Meal\r\n * @memberof CrewMealFactory\r\n * @returns {object} CrewMeal\r\n */\r\n function getCrewMealFromStorage(cateringMealId) {\r\n var crewMeals = getCrewMealsFromStorage();\r\n if (crewMeals == null)\r\n return [];\r\n var arrayLength = crewMeals.length;\r\n for (var i = 0; i < arrayLength; i++) {\r\n if (crewMeals[i].CateringMealId == cateringMealId) {\r\n return crewMeals[i];\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Checks if the specified crew meal has rating\r\n * @memberof CrewMealFactory\r\n * @returns {boolean} response\r\n */\r\n function hasRating(crewMealId) {\r\n var res = GenericService.list(\"CrewMealRatings\", objCallbackRatings);\r\n return res.some(e => e.CrewMealId === crewMealId.toString());\r\n }\r\n\r\n /**\r\n * Sends the crew meals rating report\r\n * @memberof CrewMealFactory\r\n * @returns {ratingSubmitResponseObj} ratingSubmitResponseObj\r\n */\r\n function sendCrewMealsRatingReport(ratingForm) {\r\n var objectToAdd = { CrewMealId: ratingForm.CrewMealId, TimeStamp: new Date() }\r\n return $http.post(apiUrl + '/CrewMealsRating/SaveReport', ratingForm, { 'Content-Type': 'application/json' })\r\n .then(res => saveReportSuccessCallBack(res, objectToAdd))\r\n .catch(res => saveReportFailedCallBack(res));\r\n }\r\n\r\n\r\n /**\r\n * The callback function if the save report succeed\r\n * @returns {ratingSubmitResponseObj} ratingSubmitResponseObj\r\n */\r\n function saveReportSuccessCallBack(res, objectToAdd) {\r\n ratingSubmitResponseObj.success = res.data.success;\r\n if (res.data.success) {\r\n GenericService.add(objectToAdd, \"CrewMealRatings\", objCallbackRatings);\r\n ratingSubmitResponseObj.message = \"Thank you for your feedback\";\r\n }\r\n else {\r\n ratingSubmitResponseObj.message = res.data.errorMessage\r\n }\r\n return ratingSubmitResponseObj;\r\n }\r\n\r\n /**\r\n * Gets the choices for the dropdown if a crew member did not eat their meal\r\n * @returns {ratingSubmitResponseObj} ratingSubmitResponseObj\r\n */\r\n function getCrewMealsDidNotEatReasons() {\r\n return $http.get(apiUrl + '/CrewMealsRating/GetCrewMealsDidNotEatReasons', { 'Content-Type': 'application/json' })\r\n .then((res) => {\r\n return res.data;\r\n });\r\n }\r\n\r\n /**\r\n * The callback function if the save report fail\r\n * @returns {ratingSubmitResponseObj} ratingSubmitResponseObj\r\n */\r\n function saveReportFailedCallBack(res) {\r\n ratingSubmitResponseObj.success = false;\r\n ratingSubmitResponseObj.message = \"Something went wrong!\"\r\n return ratingSubmitResponseObj;\r\n }\r\n\r\n return service;\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('CrewRouteCtrl', CrewRouteCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CrewRouteCtrl\r\n * @description \r\n * Shows the crew route information\r\n * @ngInject\r\n */\r\n function CrewRouteCtrl($scope, $filter, $route, $location, $routeParams, $uibModal, FlightFactory, SyncLogFactory, GroundDutyFactory, CrewRouteFactory) {\r\n var dutyNo = $routeParams.dutyNo;\r\n var dutyDay = $routeParams.dutyDay;\r\n $scope.crewRouteDuty = CrewRouteFactory.getCrewRouteFromStorage(dutyNo, dutyDay);\r\n \r\n var groundDuties = GroundDutyFactory.getGroundDutiesByDutyNo(dutyNo, dutyDay);\r\n if(groundDuties.length > 0){ //there are ground duties in this crew route\r\n angular.forEach(groundDuties, function(groundDuty)\r\n {\r\n groundDuty.DutyType = \"Ground\";\r\n groundDuty.Start = groundDuty.DutyBegin;\r\n });\r\n }\r\n\r\n var flights = FlightFactory.getFlightsByDutyNo(dutyNo, dutyDay);\r\n if(flights.length > 0){ //there are flights in this crew route\r\n angular.forEach(flights, function(flight)\r\n {\r\n flight.DutyType = \"Flight\";\r\n flight.Start = flight.ScheduledDeparture;\r\n });\r\n }\r\n\r\n var crewRoute = groundDuties.concat(flights);\r\n crewRoute = $filter('orderBy')(crewRoute, 'Start', false);\r\n $scope.crewRoute = crewRoute;\r\n $scope.currentDutyDay = null;\r\n $scope.differentDay = differentDay;\r\n $scope.currentPage = 1;\r\n $scope.previous = previous;\r\n $scope.next = next;\r\n $scope.openRefresh = openRefresh;\r\n $scope.dutyNo = dutyNo;\r\n $scope.dutyDay = dutyDay;\r\n $scope.firstFlightId = getFirstFlightId(); \r\n \r\n /**\r\n * Get the flightId from the first leg of the route\r\n */\r\n function getFirstFlightId(){\r\n var flightId = null;\r\n if(flights.length > 0){\r\n flightId = flights[0].FlightId;\r\n }\r\n return flightId;\r\n }\r\n\r\n /**\r\n * Checks if two dates have the same day\r\n * @param {string} day1 \r\n * @param {string} day2 \r\n */\r\n function differentDay(day1, day2){\r\n day1 = new Date(day1).trimTime().getDay();\r\n day2 = new Date(day2).trimTime().getDay();\r\n return (day1==day2) ? false : true;\r\n }\r\n\r\n /**\r\n * Moves pager to previous page\r\n */\r\n function previous(){\r\n if($scope.currentPage != 1)\r\n $scope.currentPage--;\r\n }\r\n\r\n /**\r\n * Moves pager to next page\r\n */\r\n function next(){\r\n if($scope.currentPage != crewRoute.length)\r\n $scope.currentPage++;\r\n }\r\n\r\n /**\r\n * Opens refresh modal\r\n */\r\n function openRefresh(){ \r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/CrewRoute/dlgCrewRouteRefresh.html',\r\n controller: 'CrewRouteRefreshModalCtrl',\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n crewroute: function () { return $scope.crewRoute}, \r\n crewRouteDuty: function () { return $scope.crewRouteDuty; },\r\n dutyNo: function () { return Number(dutyNo) },\r\n dutyDay: function () { return Number(dutyDay) },\r\n forCurrentDay: function() { return null}\r\n }\r\n });\r\n \r\n modalInstance.result.then(function (transferData) {\r\n if(transferData.sync){\r\n SyncLogFactory.forceSync();\r\n $location.path(\"/\"); //crew route has significantly changed\r\n }\r\n else if(transferData.refresh){\r\n $route.reload(); //crew route was updated\r\n }\r\n });\r\n }\r\n }\r\n })();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('CrewRouteFactory', CrewRouteFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CrewRouteFactory\r\n * @description \r\n * Get and Update Crew Routes \r\n * @ngInject\r\n */ \r\nfunction CrewRouteFactory(GenericService, FlightFactory, GroundDutyFactory, $filter, AircaftPositionsFactory, CrewMealFactory, FlightDelaysFactory) {\r\n\r\n\t\tvar objType ='crewRoute';\r\n\t\tvar objCallback = CrewRoute;\r\n\r\n\t\tvar service = {\r\n getCrewRoutesFromStorage : getCrewRoutesFromStorage,\r\n setCrewRoutesToStorage : setCrewRoutesToStorage,\r\n setCourseCompleted: setCourseCompleted,\r\n setCoursePending : setCoursePending, \r\n \r\n updateCrewMealsInRoute:updateCrewMealsInRoute, \r\n updateRouteLastRefreshDate: updateRouteLastRefreshDate, \r\n getCrewRouteFromStorage: getCrewRouteFromStorage,\r\n getCrewRouteDuties : getCrewRouteDuties, \r\n getCrewRouteInfoPanel : getCrewRouteInfoPanel, \r\n getCrewRouteFlights:getCrewRouteFlights,\r\n\r\n updateCrewRouteDuty: updateCrewRouteDuty,\r\n addCrewRouteDuty : addCrewRouteDuty,\r\n getManualFlightTrainingsFromStorage: getManualFlightTrainingsFromStorage,\r\n removeFlightTraining: removeFlightTraining,\r\n insertCrewRoutesWithPendingTrainings: insertCrewRoutesWithPendingTrainings \r\n };\r\n \r\n /**\r\n * Initialize the CrewRoute\r\n * @memberof CrewRouteFactory\r\n */\r\n\t\tfunction CrewRoute() {\r\n this.DutyDay = null; \r\n this.DutyNo = null; \r\n this.Route = null;\r\n this.DutyBegin = null;\r\n this.DutyEnd = null;\r\n this.CrewMeals = [];\r\n //new property: get the value from CrewAssessmentFactory\r\n this.AssessmentInfo = null;\r\n this.LastRefreshed = null;\r\n }\r\n \r\n\r\n /**\r\n * Get Crew Routes\r\n * @memberof CrewRouteFactory\r\n * @returns {Array} CrewRoutes \r\n */\r\n\t\tfunction getCrewRoutesFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Save Crew Routes to storage\r\n * @memberof GroundDutyFactory\r\n * @param {Array} objList A list of Crew Routes\r\n */\r\n\t\tfunction setCrewRoutesToStorage(objList) {\r\n\t\t\tGenericService.saveAll(objList,objType);\r\n }\r\n\r\n /**\r\n * Get a specific Crew Route\r\n * @memberof CrewRouteFactory\r\n * @returns {object} CrewRoute\r\n */\r\n function getCrewRouteFromStorage(dutyNo, dutyDay){\r\n var crewRoutes = getCrewRoutesFromStorage();\r\n\t\t\tif (crewRoutes == null)\r\n\t\t\t\treturn [];\r\n\t\t\tvar arrayLength = crewRoutes.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (crewRoutes[i].DutyNo == dutyNo && crewRoutes[i].DutyDay == dutyDay) {\r\n\t\t\t\t\treturn crewRoutes[i];\r\n\t\t\t\t}\r\n }\r\n }\r\n\r\n function setCourseCompleted(dutyNo, dutyDay, courseId, date){\r\n var crewRoutes = getCrewRoutesFromStorage();\r\n var crewRoute = crewRoutes.find(cr => cr.DutyNo == dutyNo && cr.DutyDay == dutyDay);\r\n\r\n var flightIds = crewRoute.FlightIds\r\n var flights = FlightFactory.getFlightsFromStorage().filter(x => flightIds.includes(x.FlightId));\r\n\r\n var crewRouteCourse = crewRoute.Courses.find(x => x.CourseId == courseId && new moment(x.Date).isSame(date));\r\n if(crewRouteCourse) crewRouteCourse.Status = \"Completed\"; \r\n \r\n flights.forEach(function(flight){\r\n var flightCourse = flight.Courses.find(x => x.CourseId == courseId && new moment(x.Date).isSame(date));\r\n if(flightCourse) {\r\n flightCourse.Status = \"Completed\"; \r\n FlightFactory.updateFlight(flight);\r\n }\r\n });\r\n\r\n GenericService.saveAll(crewRoutes, objType, objCallback);\r\n }\r\n\r\n function setCoursePending(dutyNo, dutyDay, courseId, date){\r\n var crewRoutes = getCrewRoutesFromStorage();\r\n var crewRoute = crewRoutes.find(cr => cr.DutyNo == dutyNo && cr.DutyDay == dutyDay);\r\n var crewRouteCourse = crewRoute.Courses.find(x => x.CourseId == courseId && new moment(x.Date).isSame(date));\r\n if(crewRouteCourse) crewRouteCourse.Status = \"Pending\"; \r\n \r\n GenericService.saveAll(crewRoutes, objType, objCallback);\r\n }\r\n\r\n function getCrewRouteDuties(dutyNo, dutyDay, flightDate) { \r\n var groundDuties = GroundDutyFactory.getGroundDutiesByDutyNo(dutyNo, dutyDay).filter(x => x.DutyDate == flightDate);\r\n \r\n if(groundDuties.length > 0){ //there are ground duties in this crew route\r\n angular.forEach(groundDuties, function(groundDuty)\r\n {\r\n groundDuty.DutyType = \"Ground\";\r\n groundDuty.Start = groundDuty.DutyBegin;\r\n // groundDuty.Date = groundDuty.DutyDate;\r\n });\r\n }\r\n \r\n // var flights = FlightFactory.getFlightsByDutyNo(dutyNo, dutyDay).filter(x => x.DutyDate == flightDate);\r\n \r\n var flights = getCrewRouteFlights(dutyNo, dutyDay, flightDate); \r\n if(flights.length > 0){ //there are flights in this crew route\r\n angular.forEach(flights, function(flight)\r\n {\r\n flight.DutyType = \"Flight\";\r\n flight.Start = flight.ScheduledDeparture;\r\n flight.showNextAcPos = false;\r\n flight.showPreviousAcPos = false;\r\n flight.hasChangeAircraft = false; \r\n flight.isFirst = false;\r\n flight.isLast = false;\r\n flight.BTime = \"\";\r\n flight.Delay = 0;\r\n flight.ArrDelay = 0;\r\n flight.crewMeals = \"\";\r\n flight.aircaftPositions = null;\r\n flight.flightDelays = null;\r\n });\r\n }\r\n \r\n flights = $filter('orderBy')(flights, 'Start');\r\n\r\n // check if aircraft change exists \r\n\r\n flights.forEach(function(flight, index, array) {\r\n flight.isFirst = index == 0;\r\n flight.isLast = (index + 1 == array.length);\r\n\r\n if(flight.isFirst){\r\n flight.showPreviousAcPos = true; \r\n }\r\n if(flight.isLast){\r\n flight.showNextAcPos = true;\r\n }\r\n if(!flight.isFirst && flights[index-1].AcTailNo != flight.AcTailNo) {\r\n flight.showPreviousAcPos = true; \r\n } \r\n if(!flight.isLast && flights[index+1].AcTailNo != flight.AcTailNo) {\r\n flight.showNextAcPos = true; \r\n flight.hasChangeAircraft = true; \r\n } \r\n\r\n \r\n var diffMin = Date.DifferenceInMinutes(flight.ScheduledDeparture, flight.ScheduledArrival);\r\n flight.BTime = Date.MinutesToStringSimple(diffMin);\r\n \r\n flight.Delay = moment(flight.ATD).diff(moment(flight.ScheduledDeparture), 'minutes') || \"\";\r\n flight.ArrDelay = moment(flight.ATA).diff(moment(flight.ScheduledArrival), 'minutes') || \"\";\r\n flight.aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId(flight.FlightId);\r\n \r\n if (flight.aircaftPositions) { \r\n // Previous Flight\r\n flight.aircaftPositions.PreviousFlightDelay = moment(flight.aircaftPositions.PreviousATD).diff(moment(flight.aircaftPositions.PreviousSTD), 'minutes') || \"\";\r\n flight.aircaftPositions.PreviousFlightArrDelay = moment(flight.aircaftPositions.PreviousATA).diff(moment(flight.aircaftPositions.PreviousSTA), 'minutes') || \"\";\r\n\r\n var diffPreviousFlightMin = Date.DifferenceInMinutes(flight.aircaftPositions.PreviousSTD, flight.aircaftPositions.PreviousSTA);\r\n flight.aircaftPositions.PreviousFlightBTime = Date.MinutesToStringSimple(diffPreviousFlightMin);\r\n flight.aircaftPositions.PreviousDelays = FlightDelaysFactory.getFlightDelaysByFlightId(flight.aircaftPositions.PreviousFlightId);\r\n\r\n // Next Flight\r\n flight.aircaftPositions.NextFlightDelay = moment(flight.aircaftPositions.NextATD).diff(moment(flight.aircaftPositions.NextSTD), 'minutes') || \"\";\r\n flight.aircaftPositions.NextFlightArrDelay = moment(flight.aircaftPositions.NextATA).diff(moment(flight.aircaftPositions.NextSTA), 'minutes') || \"\";\r\n\r\n var diffNextFlightMin = Date.DifferenceInMinutes(flight.aircaftPositions.NextSTD, flight.aircaftPositions.NextSTA);\r\n flight.aircaftPositions.NextFlightBTime = Date.MinutesToStringSimple(diffNextFlightMin);\r\n flight.aircaftPositions.NextDelays = FlightDelaysFactory.getFlightDelaysByFlightId(flight.aircaftPositions.NextFlightId);\r\n \r\n }\r\n flight.flightDelays = FlightDelaysFactory.getFlightDelaysByFlightId(flight.FlightId);\r\n });\r\n\r\n var crewRouteDuties = groundDuties.concat(flights);\r\n crewRouteDuties = $filter('orderBy')(crewRouteDuties, 'Start');\r\n\r\n return crewRouteDuties;\r\n }\r\n\r\n function getCrewRouteFlights(dutyNo, dutyDay, flightDate){\r\n var crewRoutes = getCrewRoutesFromStorage();\r\n var crewRoute = crewRoutes.find(cr => cr.DutyNo == dutyNo && cr.DutyDay == dutyDay);\r\n\r\n var flightIds = crewRoute.FlightIds;\r\n \r\n var flights = FlightFactory.getFlightsFromStorage().filter(x => flightIds.includes(x.FlightId) && x.FlightDate == flightDate); \r\n\r\n return flights;\r\n } \r\n\r\n function updateCrewRouteDuty(flightTraining){\r\n GenericService.updateFlight(flightTraining,objType, objCallback);\r\n }\r\n\r\n function addCrewRouteDuty(flightTraining){\r\n var crewRoutes = getCrewRoutesFromStorage();\r\n var crewRoute = crewRoutes.find(cr => cr.DutyNo == flightTraining.DutyNo && cr.DutyDay == flightTraining.DutyDay);\r\n if(crewRoute) {\r\n crewRoute.isManualEntry = true;\r\n crewRoute.hasPendingCourse = true; \r\n }\r\n else{\r\n GenericService.add(flightTraining, objType, objCallback);\r\n }\r\n }\r\n\r\n function removeFlightTraining(dutyNo, dutyDay) {\r\n var crewRoutes = getCrewRoutesFromStorage();\r\n var crewRoute = crewRoutes.find(cr => cr.DutyNo == dutyNo && cr.DutyDay == dutyDay);\r\n crewRoute.isManualEntry = false;\r\n crewRoute.hasPendingCourse = false; \r\n GenericService.saveAll(crewRoutes,objType, objCallback);\r\n }\r\n\r\n /**Get manual flight trainings from storage*/\r\n function getManualFlightTrainingsFromStorage(){\r\n var crewRoutes = getCrewRoutesFromStorage();\r\n return crewRoutes.filter(x => x.isManualEntry);\r\n }\r\n \r\n function updateCrewMealsInRoute(dutyNo, dutyDay, newCrewMeals , newFlightIds){\r\n var crewRoutes = getCrewRoutesFromStorage();\r\n var crewRoute = crewRoutes.find(cr => cr.DutyNo == dutyNo && cr.DutyDay == dutyDay);\r\n\r\n var crewMealsInRoute = crewRoute.CrewMeals.filter(f=> !newFlightIds.includes(f.FlightId));\r\n crewMealsInRoute = crewMealsInRoute.concat(newCrewMeals);\r\n crewRoute.CrewMeals = crewMealsInRoute;\r\n\r\n GenericService.saveAll(crewRoutes, objType, objCallback);\r\n }\r\n\r\n function insertCrewRoutesWithPendingTrainings(instructorPendingRoutes){\r\n if(instructorPendingRoutes.length > 0){\r\n\t\t\t\tvar crewRoutes = getCrewRoutesFromStorage();\r\n\t\t\t\tvar crewRoutesIdsLS = crewRoutes.map(x=>x.DutyNo);\r\n\t\t\t\tvar routesToInsert = instructorPendingRoutes.filter(f=> !crewRoutesIdsLS.includes(f.DutyNo));\r\n if(routesToInsert.length > 0){\r\n var updatedCrewRoutesList = crewRoutes.concat(routesToInsert);\r\n GenericService.saveAll(updatedCrewRoutesList, objType, objCallback);\r\n }\t\t\t\t\r\n\t\t\t}\r\n \r\n }\r\n\r\n /**\r\n * Update last Refresh date for a specific Crew Route\r\n * @memberof CrewRouteFactory\r\n */\r\n function updateRouteLastRefreshDate(dutyNo, dutyDay){\r\n var crewRoutes = getCrewRoutesFromStorage();\r\n var crewRoute = crewRoutes.find(cr => cr.DutyNo == dutyNo && cr.DutyDay == dutyDay);\r\n crewRoute.LastRefreshed = moment().toDate().toUTC(); \r\n\r\n GenericService.saveAll(crewRoutes, objType, objCallback);\r\n }\r\n /**\r\n * Get Crew Route Info panel information (inside Flight-page)\r\n * @memberof CrewRouteFactory\r\n * @returns {object} flights\r\n */\r\n function getCrewRouteInfoPanel(flight){\r\n var panelInfo = null;\r\n var crewRouteInfo = getCrewRouteFromStorage(flight.DutyNo, flight.DutyDay);\r\n var crewRouteDuties = getCrewRouteDuties(flight.DutyNo, flight.DutyDay, flight.FlightDate);\r\n var crewRouteFlightDuties = crewRouteDuties.filter(x => x.DutyType === \"Flight\");\r\n \r\n var hasAircraftPositions = crewRouteFlightDuties.length && \r\n crewRouteFlightDuties.length > 0 && \r\n crewRouteFlightDuties[0].aircaftPositions != null;\r\n\r\n //update crewRouteDuties with the crewMeals\r\n var crewMealsPerFlightId = [];\r\n\r\n crewRouteInfo.CrewMeals.forEach(meals => {\r\n if (meals.CrewMealsCateringIds) { \r\n var crewMealsTitles = \"\";\r\n \r\n for (var j = 0; j < Object.values(meals.CrewMealsCateringIds).length; j++) {\r\n if (j != 0) {\r\n crewMealsTitles += \" & \";\r\n } \r\n var crewMealDetails = CrewMealFactory.getCrewMealFromStorage( Object.values(meals.CrewMealsCateringIds)[j]); \r\n crewMealsTitles += crewMealDetails.ShortTitle; \r\n } \r\n crewMealsPerFlightId.push({ flightId: meals.FlightId, crewMeals: crewMealsTitles }); \r\n } \r\n });\r\n \r\n if (crewMealsPerFlightId.length > 0) {\r\n crewRouteDuties.forEach(function(duty){\r\n if (duty.FlightId == crewMealsPerFlightId[0].flightId) {\r\n duty.crewMeals = crewMealsPerFlightId[0].crewMeals;\r\n } \r\n });\r\n } \r\n \r\n var routeNeedRefresh = false; \r\n if(!crewRouteInfo.LastRefreshed){\r\n routeNeedRefresh = true; \r\n }\r\n\r\n return panelInfo = \r\n { \r\n crewRouteDuties : crewRouteDuties, \r\n routeNeedRefresh: routeNeedRefresh,\r\n \r\n hasAircraftPositions : hasAircraftPositions \r\n };\r\n }\r\n\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('CrewRouteRefreshModalCtrl', CrewRouteRefreshModalCtrl)\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CrewRouteRefreshModalCtrl\r\n * @description \r\n * \r\n * @ngInject\r\n */\r\n\r\n function CrewRouteRefreshModalCtrl($scope, $filter, $uibModalInstance, crewroute, crewRouteDuty, dutyNo, dutyDay, forCurrentDay, \r\n InfoAPIService, FlightSessionFactory, CourseFactory, AirportContactFactory, CrewRouteFactory, LuggageComplianceFactory,\r\n GroundServicesFactory, AircraftDifferencesFactory, AirportHotelFactory, TimeLogFactory, CrewCallFactory, PreviousDutyFactory,\r\n CampaignFactory, AimsCrewMemosFactory, FlightDelaysFactory, CustomerEventHistoryFactory, FlightServiceEventsFactory ) \r\n {\r\n //timer\r\n var t0 = performance.now();\r\n var timeLog = \"RefreshFlight: \";\r\n var tFrom = 0;\r\n var tTo = 0;\r\n // tFrom = performance.now();\r\n // //do smth\r\n // tTo = performance.now();\r\n // timeLog = timeLog + \" | smthTime: \" + (tTo-tFrom); \r\n \r\n $scope.isRefreshing = true;\r\n $scope.refreshResultsVisible = false;\r\n $scope.error = false;\r\n $scope.sync = false;\r\n $scope.collapse = collapse\r\n $scope.close = close;\r\n $scope.crewroute = crewroute;\r\n $scope.crewRouteDuty = crewRouteDuty;\r\n $scope.crewRouteGeneral = {statuses: [], isCollapsed:false};\r\n \r\n //For refresh Flight page: forCurrentDay is not null\r\n if(forCurrentDay){\r\n //Get only the flights from the current day\r\n var currentDayDuties = crewroute.filter(function (item) {\r\n return (item.DutyType == 'Flight'&& item.FlightDate == forCurrentDay)\r\n || (item.DutyType == 'Ground'&& item.DutyDate == forCurrentDay);\r\n });\r\n crewroute = currentDayDuties;\r\n $scope.crewroute = currentDayDuties;\r\n crewRouteDuty.CurrentDutyDate = forCurrentDay;\r\n \r\n if(currentDayDuties.some(s=>s.DutyType == 'Flight')){\r\n $scope.crewRouteGeneral.statuses = [\r\n {\r\n datatype: \"Meals\", \r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Campaigns\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Hotels\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Airport Contacts\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Ground Services\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Aircraft Differences\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Aims Memos\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Flight Service Events\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n }\r\n\r\n ];\r\n }\r\n \r\n }\r\n\r\n //add DataStatus to each duty\r\n for (var i = 0; i < crewroute.length; i++) {\r\n if (crewroute[i].DutyType == 'Flight') {\r\n\r\n crewroute[i].DataStatus = [\r\n {\r\n datatype: \"Flight Status\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Aircraft Movement\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Crew Info\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Crew Contacts\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Pax Info\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n }, \r\n {\r\n datatype: \"Connections\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Luggage Info\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Training Info\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n \r\n ];\r\n\r\n \r\n }\r\n else if (crewroute[i].DutyType == 'Ground') {\r\n if (crewroute[i].isTraining) {\r\n crewroute[i].DataStatus = [\r\n {\r\n datatype: \"Duty Info\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Instructors\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n {\r\n datatype: \"Trainees\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n }\r\n ]\r\n }\r\n else {\r\n crewroute[i].DataStatus = [\r\n {\r\n datatype: \"Duty Info\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n }\r\n ]\r\n }\r\n\r\n }\r\n\r\n }\r\n\r\n //separate flights and groundDuties \r\n var currentFlights = [];\r\n var currentGroundDuties = [];\r\n for (var i = 0; i < crewroute.length; i++) {\r\n if (crewroute[i].DutyType == 'Flight') currentFlights.push(crewroute[i]);\r\n else if (crewroute[i].DutyType == 'Ground') currentGroundDuties.push(crewroute[i]);\r\n\r\n crewroute[i].isCollapsed = false;\r\n }\r\n //get latest info\r\n InfoAPIService.refreshCrewRoute(crewRouteDuty, function (responseData) {\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | apiResponseTime: \" + (tTo-t0); \r\n\r\n $scope.isRefreshing = false;\r\n var response = responseData.data.data; \r\n var responseStatuses = {\r\n meals: false, \r\n airportContacts: false, \r\n groundServices: false, \r\n aircraftDifferences: false, \r\n airportHotels: false, \r\n campaigns: false,\r\n crewAimsMemos: false,\r\n flightServiceEvents: false\r\n };\r\n if (forCurrentDay){\r\n \r\n //Update CrewMeals in the current route // only for refresh flight\r\n if(response.CrewMeals != undefined && response.CrewMeals != null ){\r\n var responseFlightIds = response.Flights.map(x=> x.FlightInfo.FlightId);\r\n tFrom = performance.now();\r\n \r\n CrewRouteFactory.updateCrewMealsInRoute(dutyNo, dutyDay, response.CrewMeals , responseFlightIds);\r\n responseStatuses.meals = true\r\n \r\n tTo = performance.now();\r\n timeLog = timeLog + \" | updateCrewMealsInRoute: \" + (tTo-tFrom); \r\n }\r\n \r\n // Update Airport Contacts\r\n if (response.AirportContacts && response.AirportContacts.length > 0) {\r\n tFrom = performance.now();\r\n AirportContactFactory.upsertAirportContacts(response.AirportContacts);\r\n responseStatuses.airportContacts = true;\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | upsertAirportContacts: \" + (tTo-tFrom); \r\n }\r\n\r\n // Update ground services\r\n if (response.GroundServices && response.GroundServices.length > 0) {\r\n tFrom = performance.now();\r\n GroundServicesFactory.upsertGroundServices(response.GroundServices);\r\n responseStatuses.groundServices = true;\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | upsertGroundServices: \" + (tTo-tFrom); \r\n }\r\n \r\n // Update aircraft differences\r\n if (response.AircraftDifferences && response.AircraftDifferences.length > 0) {\r\n tFrom = performance.now();\r\n AircraftDifferencesFactory.upsertAircraftDifferences(response.AircraftDifferences);\r\n responseStatuses.aircraftDifferences = true;\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | upsertAircraftDifferences: \" + (tTo-tFrom); \r\n }\r\n\r\n // Update airport hotels\r\n if (response.AirportHotels && response.AirportHotels.length > 0) {\r\n tFrom = performance.now();\r\n AirportHotelFactory.upsertAirportHotels(response.AirportHotels);\r\n responseStatuses.airportHotels = true;\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | upsertAirportHotels: \" + (tTo-tFrom); \r\n }\r\n\r\n // Update Aims Crew Memos\r\n if (response.CrewAimsMemos && response.CrewAimsMemos.length > 0) {\r\n tFrom = performance.now();\r\n AimsCrewMemosFactory.upsertAimsCrewMemos(response.CrewAimsMemos);\r\n responseStatuses.crewAimsMemos = true;\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | upsertAimsCrewMemos: \" + (tTo-tFrom); \r\n }\r\n\r\n // Update campaigns\r\n if (response.Campaigns && response.Campaigns.FlightsCampaigns.length > 0) {\r\n tFrom = performance.now();\r\n CampaignFactory.mergeCampaigns(response.Campaigns);\r\n responseStatuses.campaigns = true;\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | mergeCampaigns: \" + (tTo-tFrom); \r\n }\r\n\r\n // Update Flight Delays\r\n if (response.FlightDelays && response.FlightDelays.length > 0) {\r\n tFrom = performance.now();\r\n FlightDelaysFactory.upsertFlightDelays(response.FlightDelays);\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | upsertFlightDelays: \" + (tTo-tFrom); \r\n }\r\n\r\n //Get Customer Event History - one stop shop\r\n if (response.OneStopShop && response.OneStopShop.CustomerEventHistory && response.OneStopShop.CustomerEventHistory.length > 0) {\r\n tFrom = performance.now();\r\n CustomerEventHistoryFactory.refreshPassengerHistory(response.OneStopShop.CustomerEventHistory);\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | mergeCampaigns: \" + (tTo-tFrom);\r\n }\r\n\r\n //Get flight service events\r\n if (response.FlightServiceEvents && response.FlightServiceEvents.length > 0) {\r\n tFrom = performance.now();\r\n responseStatuses.flightServiceEvents = true;\r\n FlightServiceEventsFactory.upsertEvents(response.FlightServiceEvents);\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | upsertFlightServiceEvents \" + (tTo-tFrom);\r\n }\r\n \r\n }\r\n\r\n //if there are significant changes in crew route user should sync\r\n tFrom = performance.now();\r\n var needsSynchCheck = needsSynch(currentFlights, response.Flights, currentGroundDuties, response.GroundDuties); \r\n tTo = performance.now();\r\n timeLog = timeLog + \" | needsSynchCheck: \" + (tTo-tFrom);\r\n if (needsSynchCheck) {\r\n $scope.sync = true;\r\n }\r\n else {\r\n //Manage details info and Update local storage\r\n if (response.Flights.length) {\r\n //Manage crew route statuses\r\n tFrom = performance.now();\r\n InfoAPIService.updateCrewRouteStatusSetter($scope.crewRouteGeneral.statuses, responseStatuses);\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | updateCrewRouteStatusSetter: \" + (tTo-tFrom);\r\n\r\n tFrom = performance.now();\r\n setupFlightInfo(response.Flights);\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | setupFlightInfo: \" + (tTo-tFrom);\r\n \r\n tFrom = performance.now();\r\n updateFlights(response.Flights);\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | updateFlights: \" + (tTo-tFrom);\r\n\r\n\r\n //Save training\r\n tFrom = performance.now();\r\n response.Flights.forEach(function(flight){\r\n var trainingCourses = flight.TrainingCourses;\r\n if(trainingCourses && trainingCourses.length && flight.FlightInfo){\r\n trainingCourses.forEach(function(trainingCourse){\r\n CourseFactory.upsertCourse(trainingCourse, function(course) {\r\n FlightSessionFactory.applyTraineeInfoToSession(course, course.Id, new moment(flight.FlightInfo.FlightDate).format(\"YYYY-MM-DD\"), dutyNo, dutyDay, function(session) {\r\n });\r\n });\r\n });\r\n }\r\n });\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | SaveTraining: \" + (tTo-tFrom);\r\n \r\n }\r\n if (response.GroundDuties.length) {\r\n tFrom = performance.now();\r\n setupGroundInfo(response.GroundDuties);\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | setupGroundInfo: \" + (tTo-tFrom);\r\n tFrom = performance.now();\r\n updateGroundDuties(response.GroundDuties);\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | updateGroundDuties: \" + (tTo-tFrom);\r\n }\r\n\r\n $scope.refreshResultsVisible = true;\r\n\r\n tFrom = performance.now();\r\n CrewRouteFactory.updateRouteLastRefreshDate(dutyNo, dutyDay);\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | updateRouteLastRefreshDate: \" + (tTo-tFrom);\r\n\r\n tTo = performance.now();\r\n timeLog = timeLog + \" | Start-End: \" + (tTo-t0);\r\n TimeLogFactory.timeLogToStorage(timeLog, response.Timelog);\r\n }\r\n })\r\n .catch(function () {\r\n $scope.error = true;\r\n $scope.isRefreshing = false;\r\n });\r\n\r\n /**\r\n * Checks if crew route has significantly changed and needs sync\r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {array} currentFlights Array of current flights\r\n * @param {array} newFlights Array of newly fetched flights\r\n * @param {array} currentGroundDuties Array of current ground duties\r\n * @param {array} newGroundDuties Array of newly fetched ground duties\r\n */\r\n function needsSynch(currentFlights, newFlights, currentGroundDuties, newGroundDuties) {\r\n var sync = false;\r\n //1.Crew Route may not exist any more\r\n if (!newFlights.length && !newGroundDuties.length) {\r\n sync = true;\r\n }\r\n //2.Duties may have been added/removed \r\n else if ((newFlights.length != currentFlights.length) || (newGroundDuties.length != currentGroundDuties.length)) {\r\n sync = true; //different size arrays\r\n }\r\n else { //same size arrays\r\n if (currentFlights.length && newFlights.length) { //compare current with new flights\r\n\r\n currentFlights = $filter('orderBy')(currentFlights, 'FlightId');\r\n newFlights = $filter('orderBy')(newFlights, 'FlightInfo.FlightId');\r\n for (var i = 0; i < currentFlights.length; i++) {\r\n if (newFlights[i].FlightInfo && currentFlights[i].FlightId != newFlights[i].FlightInfo.FlightId) {\r\n sync = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n if (currentGroundDuties.length && newGroundDuties.length) { //compare current with new ground duties\r\n currentGroundDuties = $filter('orderBy')(currentGroundDuties, 'Id');\r\n newGroundDuties = $filter('orderBy')(newGroundDuties, 'Id');\r\n for (var i = 0; i < currentGroundDuties.length; i++) {\r\n if (currentGroundDuties[i].Id != newGroundDuties[i].Id) {\r\n sync = true;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n return sync;\r\n }\r\n\r\n /**\r\n * Updates Flight in Local Storage\r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {array} newFlights \r\n */\r\n function updateFlights(newFlights) {\r\n for (var i = 0; i < newFlights.length; i++) {\r\n InfoAPIService.updateFlightLocalStorage(newFlights[i]);\r\n InfoAPIService.updatePhiloxeniaQuestions(newFlights[i]);\r\n LuggageComplianceFactory.updateLuggageComplianceStorage(newFlights[i].LuggageCompliance, newFlights[i].FlightId);\r\n InfoAPIService.updateCrewCheckIn(newFlights[i]);\r\n \r\n //Update previous Duties & phone calls\r\n //1. First remove all additional info (phone numbers & previous duties) for this flight\r\n CrewCallFactory.cleanFlightCrewNumbers(newFlights[i].FlightInfo.FlightId);\r\n PreviousDutyFactory.cleanFlightPreviousDuties(newFlights[i].FlightInfo.FlightId);\r\n //2. Then save any fetched info\r\n if( newFlights[i].FlightInfo){\r\n var crew = newFlights[i].FlightInfo.crew;\r\n CrewCallFactory.saveFlightPhoneNumbers(newFlights[i].FlightInfo.FlightId, crew, newFlights[i].FlightInfo.ScheduledArrival, newFlights[i].FlightInfo.ScheduledDeparture);\r\n PreviousDutyFactory.saveFlightPreviousDuties(newFlights[i].FlightInfo.FlightId, crew);\r\n } \r\n\r\n }\r\n }\r\n\r\n /**\r\n * Updates Flight's Data Status\r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {array} newFlights \r\n */\r\n function setupFlightInfo(newFlights) {\r\n newFlights = $filter('orderBy')(newFlights, 'Start', false);\r\n currentFlights = $filter('orderBy')(currentFlights, 'Start', false);\r\n \r\n for (var i = 0; i < newFlights.length; i++) {\r\n InfoAPIService.updateFlightStatusSetter(newFlights[i], currentFlights[i].DataStatus);\r\n }\r\n }\r\n\r\n /**\r\n * Updates Ground Duty's Data Status\r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {array} newGroundDuties \r\n */\r\n function setupGroundInfo(newGroundDuties) {\r\n newGroundDuties = $filter('orderBy')(newGroundDuties, 'Start', false);\r\n currentGroundDuties = $filter('orderBy')(currentGroundDuties, 'Start', false);\r\n\r\n for (var i = 0; i < newGroundDuties.length; i++) {\r\n InfoAPIService.updateGroundStatusSetter(newGroundDuties[i], currentGroundDuties[i].DataStatus);\r\n }\r\n }\r\n\r\n /**\r\n * Updates Ground Duty in Local Storage\r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {array} newFlights \r\n */\r\n function updateGroundDuties(newGroundDuties) {\r\n for (var i = 0; i < newGroundDuties.length; i++) {\r\n InfoAPIService.updateGroundDutyLocalStorage(newGroundDuties[i]);\r\n }\r\n }\r\n\r\n /**\r\n * Shows Details \r\n * @memberof CrewRouteRefreshModalCtrl\r\n * @param {object} duty \r\n */\r\n function collapse(duty) {\r\n if (!$scope.isRefreshing && $scope.refreshResultsVisible)\r\n duty.isCollapsed = !duty.isCollapsed;\r\n }\r\n\r\n /**\r\n * Closes the modal\r\n * @memberof CrewRouteRefreshModalCtrl\r\n */\r\n function close() {\r\n $uibModalInstance.close({ sync: $scope.sync, refresh: $scope.refreshResultsVisible });\r\n }\r\n\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('CustomerModalCtrl', CustomerModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CustomerCtrl\r\n * @description \r\n * Report a bug of the application\r\n * @ngInject\r\n */\r\nfunction CustomerModalCtrl($scope, $uibModalInstance, $timeout, InfoAPIService, customerIncident) {\r\n $scope.successful = false;\r\n $scope.error = false;\r\n\r\n\r\n var q = InfoAPIService.sendCustomerIncident(customerIncident.flightDescription,customerIncident.question, customerIncident.description, customerIncident.image);\r\n\r\n q.then(function(responseData){\r\n\t\t\tif(responseData.data.data){\r\n $scope.successful = true;\r\n\t\t\t}\r\n\t\t\telse {\r\n $scope.error = true;\r\n\t\t\t}\r\n $timeout(function() {\r\n\t\t\t\t\t$uibModalInstance.close();\r\n }, 3000);\r\n\t\t},\r\n\t\tfunction(){\r\n $scope.error = true;\r\n $timeout(function() {\r\n\t\t\t\t\t$uibModalInstance.close();\r\n }, 3000);\r\n\t\t});\r\n}\r\n \r\n \r\n})();\r\n ","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('aircraftDifferences',aircraftDifferences);\r\n\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name aircraftDifferences\r\n * @restrict E\r\n * @description\r\n * Implementation of aircraft differences\r\n *\r\n * Display the differences of Aircrafts\r\n * @attr {String} registration The registration of the aircraft.\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */ \r\nfunction aircraftDifferences(AircraftDifferencesFactory) {\r\n function link(scope, element, attributes){\r\n \r\n var AircraftDifferencesObj = AircraftDifferencesFactory.getAircraftDifferenceFromStorageByRegistration(attributes.registration); \r\n scope.AircraftDifferences = AircraftDifferencesObj != null && AircraftDifferencesObj.AircraftDifferences != null ? AircraftDifferencesObj.AircraftDifferences : []; \r\n\r\n \r\n }\r\n \r\n \r\n return {\r\n\t\t\trestrict: 'E',\r\n\t\t\tterminal: true,\r\n\t\t\ttemplateUrl: 'views/directives/aircraftDifferences.tpl.html',\r\n\t\t\tscope: false,\r\n link: link\r\n\t\t}\r\n}\r\n })();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('autorefresh', autorefresh);\r\n\r\n function autorefresh($interval, $timeout, PushNotifier, InfoAPIService, FlightFactory, PaxInfoFactory, \r\n AircaftPositionsFactory, CrewCallFactory, PreviousDutyFactory, CrewRouteFactory) {\r\n\r\n function link($scope, element, attrs) {\r\n\r\n //var flight = $scope.flight;\r\n //$scope.flight from parent scope\r\n\r\n //Auto refresh functionality start\r\n var browserNotificationsEnabled = false;\r\n var autoUpdateInterval = null;\r\n var autoUpdateIntervalTimeOffset = null;\r\n $scope.showAlternativeNotifications = false;\r\n $scope.showAutoUpdatePanel = false;\r\n\r\n //Check if push notification are enabled\r\n PushNotifier.CheckForPermissionsAndSupport().then(function (res) {\r\n browserNotificationsEnabled = res\r\n });\r\n\r\n var ScheduledDepartureTimeStamp = 0;\r\n if($scope.flight){\r\n ScheduledDepartureTimeStamp = moment.utc($scope.flight.ScheduledDeparture).valueOf();\r\n }\r\n var now = moment().valueOf();\r\n\r\n $scope.showAutoUpdatePanel = (ScheduledDepartureTimeStamp - (70 * 60000)) <= now\r\n && (ScheduledDepartureTimeStamp + (30 * 60000)) >= now\r\n && $scope.flight.DepartureEU;\r\n\r\n $scope.radioModel = false;\r\n\r\n $scope.$watch('radioModel', function (value) {\r\n if (value == true)\r\n autoflightInfoInterval();\r\n if (value == false) {\r\n $interval.cancel(autoUpdateInterval);\r\n autoUpdateInterval = null;\r\n }\r\n });\r\n\r\n function autoflightInfoInterval() {\r\n var intervalTime = timerDelayGenerator($scope.flight.ScheduledDeparture);\r\n var currentInfo = null;\r\n PushNotifier.formatInfoToCompare($scope.flight.FlightId)\r\n .then(function (data) {\r\n currentInfo = data;\r\n\r\n if (intervalTime > 0) {\r\n InfoAPIService.getPax($scope.flight.FlightId)\r\n .then(function (responseData) {\r\n $scope.flight = FlightFactory.getFlightFromTotalFlights($scope.flight.FlightId);\r\n\r\n //UPDATE CREW INFO\r\n //1. First remove all additional info (phone numbers & previous duties) for this flight\r\n CrewCallFactory.cleanFlightCrewNumbers($scope.flight.FlightId);\r\n PreviousDutyFactory.cleanFlightPreviousDuties($scope.flight.FlightId);\r\n\r\n //2. Then save any fetched info\r\n if( responseData.data.data.FlightInfo){\r\n var crew = responseData.data.data.FlightInfo.crew;\r\n CrewCallFactory.saveFlightPhoneNumbers($scope.flight.FlightId, crew, $scope.flight.ScheduledArrival, $scope.flight.ScheduledDeparture);\r\n PreviousDutyFactory.saveFlightPreviousDuties($scope.flight.FlightId, crew);\r\n }\r\n\r\n PaxInfoFactory.getPaxInfoFromStorage($scope.flight.FlightId, function (paxInfo) {\r\n $scope.paxInfo = paxInfo;\r\n \r\n \r\n if (paxInfo) {\r\n\r\n $scope.cStat = (paxInfo.PaxTotalC / paxInfo.ConfigurationC) * 100;\r\n $scope.yStat = (paxInfo.PaxTotalY / paxInfo.ConfigurationY) * 100;\r\n\r\n $scope.mealsChart = $scope.generateMealChart(paxInfo);\r\n\r\n var listSentTimestamp = new Date(paxInfo.LastRun).getTime();\r\n var DepartureTimestamp = new Date($scope.flight.ScheduledDeparture).getTime();\r\n //20 minutes before takeoff\r\n if (DepartureTimestamp - listSentTimestamp <= 1200000) {\r\n $scope.IsProvisional = false;\r\n }\r\n }\r\n });\r\n \r\n //Update scopes for the CrewRoutePanel in Flight-page\r\n $scope.crewRouteInfoPanel = CrewRouteFactory.getCrewRouteInfoPanel($scope.flight);\r\n\r\n $scope.aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId($scope.flight.FlightId);\r\n\r\n $scope.flightETA = $scope.flight.ETA ?\r\n moment($scope.flight.ETA).valueOf() : new Date($scope.flight.ScheduledArrival).getTime();\r\n\r\n var updatedInfo = null;\r\n PushNotifier.formatInfoToCompare($scope.flight.FlightId).then(function (data) {\r\n updatedInfo = data;\r\n\r\n var changes = PushNotifier.compareAndExtractChanges(currentInfo, updatedInfo);\r\n var message = PushNotifier.MessageGenerator(changes);\r\n\r\n if (changes && changes.length > 0) {\r\n if (browserNotificationsEnabled) {\r\n try {\r\n PushNotifier.Generate('Changes', message);\r\n } catch (e) {\r\n $scope.changes = changes;\r\n $scope.showAlternativeNotifications = true;\r\n }\r\n } else {\r\n $scope.changes = changes;\r\n $scope.showAlternativeNotifications = true;\r\n }\r\n }\r\n\r\n \r\n });\r\n\r\n },\r\n function (responseData) {\r\n if (browserNotificationsEnabled && window.navigator.onLine) {\r\n try {\r\n PushNotifier.Generate('Changes', 'Update failed');\r\n } catch(ex){\r\n //TODO: add related messagge KVEN,EPAP\r\n }\r\n }\r\n });\r\n \r\n if (intervalTime != autoUpdateIntervalTimeOffset) {\r\n autoUpdateIntervalTimeOffset = intervalTime;\r\n $interval.cancel(autoUpdateInterval);\r\n autoUpdateInterval = $interval(autoflightInfoInterval, autoUpdateIntervalTimeOffset);\r\n }\r\n\r\n } else {\r\n $interval.cancel(autoUpdateInterval);\r\n $scope.showAutoUpdatePanel = false;\r\n }\r\n });\r\n }\r\n\r\n function timerDelayGenerator(departureTime) {\r\n var intervalTime = -1;\r\n var depTimestamp = moment.utc(departureTime).valueOf();\r\n var nowTimeStamp = moment().valueOf();\r\n\r\n var minutes = 60000;\r\n if (depTimestamp - 70 * minutes <= nowTimeStamp && depTimestamp + 30 * minutes >= nowTimeStamp) {\r\n var absoluteMinuteDiff = Math.abs(depTimestamp - nowTimeStamp);\r\n if (absoluteMinuteDiff <= 15 * minutes) {\r\n intervalTime = 1 * minutes;\r\n } else {\r\n intervalTime = 3 * minutes;\r\n }\r\n }\r\n return intervalTime;\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n templateUrl: 'views/directives/autofresh.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})(); ","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('campaigns', campaigns);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name campaigns\r\n * @restrict E\r\n * @description\r\n * Implementation of issues\r\n *\r\n * Initialize the campaigns template\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function campaigns($uibModal, CampaignFactory) {\r\n\r\n function link(scope) {\r\n scope.currentTreatment = 0;\r\n scope.previousTreatment = previousTreatment;\r\n scope.nextTreatment = nextTreatment;\r\n scope.openAssignment = openAssignment;\r\n scope.FlightCampaigns = {};\r\n\r\n //Keeps modified accordion group open\r\n scope.status = { isItemOpen: new Array(scope.FlightCampaigns.length) };\r\n\r\n checkForCompletion();\r\n\r\n function openAssignment(assignment, flightId, campaign, treatment, cindex) {\r\n\r\n scope.status.isItemOpen[cindex] = true;\r\n\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgCampaignAssignment.html',\r\n controller: 'AssignmentModalCtrl',\r\n size: 'md',\r\n keyboard: false,\r\n resolve: {\r\n assignment: function () {\r\n return { ...assignment };\r\n },\r\n info: function () {\r\n return { flightId: +flightId, campaign: campaign, treatment: treatment };\r\n }\r\n }\r\n });\r\n\r\n modalInstance.closed.then(function () {\r\n scope.campaigns = CampaignFactory.getCampaignsByFlightId(+flightId);\r\n checkForCompletion();\r\n });\r\n }\r\n\r\n function previousTreatment(index) {\r\n if (index > 0)\r\n scope.currentTreatment = index - 1;\r\n }\r\n\r\n function nextTreatment(index, lenght) {\r\n if (index < lenght - 1)\r\n scope.currentTreatment = index + 1;\r\n }\r\n\r\n function isOpen(index) {\r\n return latestOpen == index;\r\n }\r\n\r\n function checkForCompletion() {\r\n if (scope.campaigns && scope.campaigns.CampaignsList && scope.campaigns.CampaignsList.length > 0) {\r\n scope.campaigns.CampaignsList.forEach(function (c) {\r\n c.Treatments.forEach(function (t) {\r\n\r\n var assignmentsWithStatus = t.Assignments.filter(function (a) { return +a.Status > 0 });\r\n t.CompleteFeedbacksCount = assignmentsWithStatus.length;\r\n\r\n var feedbacksCompleted = t.Assignments.every(function (a) {\r\n return a.Status > 0;\r\n });\r\n\r\n if (feedbacksCompleted) {\r\n t.FeedbacksCompleted = true;\r\n } else {\r\n t.FeedbacksCompleted = false;\r\n }\r\n });\r\n\r\n var campaignCompleted = c.Treatments.every(function (t) {\r\n return t.FeedbacksCompleted == true;\r\n });\r\n\r\n if (campaignCompleted) {\r\n c.TreamentsCompleted = true;\r\n } else {\r\n c.TreamentsCompleted = false;\r\n }\r\n });\r\n\r\n scope.FlightCampaigns = scope.campaigns;\r\n scope.flight.hasPendingFeedbacks = CampaignFactory.hasPendingFeedbacks(scope.campaigns);\r\n }\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n scope: {\r\n campaigns: '@'\r\n },\r\n terminal: true,\r\n templateUrl: 'views/directives/campaigns.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n})();\r\n","(function () {\r\n 'use strict';\r\n a3_cabin_reports.directive('crewMeals', crewMeals);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name crewMeals\r\n * @restrict E\r\n * @description\r\n * Implementation of crew meals\r\n *\r\n * Display the crew meals\r\n * @attr {String} dutyNo \r\n * @attr {String} dutyDay \r\n * @attr {String} flight-id\r\n * @example\r\n * Usage:\r\n * \r\n * \r\n * @ngInject\r\n */\r\n function crewMeals(CrewRouteFactory, CrewMealFactory, FlightFactory, $sce, $timeout) {\r\n /**\r\n * Initialize crewMeals\r\n * @memberof crewMeals\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\r\n function link(scope, element, attributes) {\r\n scope.togglePanel = togglePanel;\r\n scope.route = CrewRouteFactory.getCrewRouteFromStorage(scope.dutyNo, scope.dutyDay);\r\n scope.HasRegChanged = false;\r\n scope.noClicked = noClicked;\r\n scope.yesClicked = yesClicked;\r\n scope.submitRatingClicked = submitRatingClicked;\r\n scope.canceClicked = canceClicked;\r\n scope.clearFormData = clearFormData;\r\n //for flight page\r\n scope.isFlightPanel = scope.flightId !== \"\";\r\n scope.flightCrewMeals = null;\r\n //for route page\r\n scope.isRoutePanel = scope.flightId == null || scope.flightId === \"\";\r\n scope.routeCrewMeals = [];\r\n scope.showCrewMealsPanel = false;\r\n //Rating Form\r\n scope.ratingForm = { CateringMealId: '', FlightId: '', Rating: '', Comments: '', DidNotEatReasonId: '' };\r\n scope.submitRatingMessage = '';\r\n scope.showPanel = \"meals\";\r\n scope.DidNotEatReasons = [];\r\n scope.isOffline = !window.navigator.onLine;\r\n\r\n scope.popoverInfo = {\r\n title: $sce.trustAsHtml(' Attention'),\r\n contentHtml: $sce.trustAsHtml('
' +\r\n 'There is an aircraft change on your route. Please arrange to take your assigned meal with you.' +\r\n '
')\r\n };\r\n\r\n window.addEventListener('offline', function (e) { $timeout(scope.isOffline = !window.navigator.onLine); });\r\n window.addEventListener('online', function (e) { $timeout(scope.isOffline = !window.navigator.onLine); });\r\n\r\n //Get scope values\r\n if (scope.isFlightPanel && scope.route) {\r\n var crewMeals = scope.route.CrewMeals;\r\n for (var i = 0; i < crewMeals.length; i++) {\r\n if (crewMeals[i].FlightId == scope.flightId) {\r\n scope.flightCrewMeals = new FlightCrewMeal(crewMeals[i]);\r\n scope.showCrewMealsPanel = true;\r\n break;\r\n }\r\n }\r\n scope.HasRegChanged = hasRegChanged(scope.flightId);\r\n }\r\n if (scope.isRoutePanel && scope.route && scope.route.CrewMeals.length > 0) {\r\n var crewMeals = scope.route.CrewMeals;\r\n for (var i = 0; i < crewMeals.length; i++) {\r\n scope.routeCrewMeals.push(new FlightCrewMeal(crewMeals[i]));\r\n scope.showCrewMealsPanel = true;\r\n }\r\n scope.HasRegChanged = hasRegChanged(crewMeals[0].FlightId);\r\n }\r\n\r\n if (!scope.isOffline && scope.showCrewMealsPanel) {\r\n CrewMealFactory.getCrewMealsDidNotEatReasons()\r\n .then(res => scope.DidNotEatReasons = res);\r\n }\r\n\r\n //FlightCrewMeal Constructor\r\n function FlightCrewMeal(flight) {\r\n this.FlightDate = moment(flight.FlightDate).format(\"DD/MM\");\r\n this.FlightNo = flight.FlightNo;\r\n this.FlightDeparture = flight.FlightDeparture;\r\n this.CrewMeals = \"\";\r\n this.CrewMealsDescriptions = [];\r\n\r\n for (var i = 0; i 0) {\r\n var acTailNo = flights[0].AcTailNo;\r\n for (var i = 0; i < flights.length; i++) {\r\n if (flights[i].AcTailNo != acTailNo) {\r\n retVal = true;\r\n break;\r\n }\r\n }\r\n }\r\n return retVal;\r\n }\r\n\r\n /**\r\n * toggle Panel\r\n * @memberof crewMeals\r\n * @param {number} panelId\r\n */\r\n function togglePanel(panelId) {\r\n $('#' + panelId).toggle();\r\n }\r\n\r\n function noClicked(cateringMealId, crewMealId) {\r\n clearFormData(cateringMealId, crewMealId)\r\n scope.showPanel = \"didNotEatMeal\";\r\n }\r\n\r\n function yesClicked(cateringMealId, crewMealId) {\r\n clearFormData(cateringMealId, crewMealId);\r\n scope.showPanel = \"mealRating\";\r\n }\r\n\r\n //function checkConnection\r\n\r\n function clearFormData(cateringMealId, crewMealId) {\r\n scope.ratingForm.CateringMealId = cateringMealId;\r\n scope.ratingForm.FlightId = scope.flightId;\r\n scope.ratingForm.CrewMealId = crewMealId;\r\n scope.ratingForm.Rating = '';\r\n scope.ratingForm.DidNotEatReasonId = '';\r\n scope.ratingForm.Comments = '';\r\n scope.isOffline = !window.navigator.onLine\r\n }\r\n\r\n function canceClicked() {\r\n scope.showPanel = \"meals\";\r\n }\r\n\r\n function submitRatingClicked() {\r\n scope.showPanel = \"loading\";\r\n CrewMealFactory.sendCrewMealsRatingReport(this.ratingForm)\r\n .then(res => handleSubmitResponse(res));\r\n\r\n }\r\n\r\n function handleSubmitResponse(res) {\r\n if (res.success) {\r\n var index = scope.flightCrewMeals.CrewMealsDescriptions.findIndex((x => x.CateringMealId == scope.ratingForm.CateringMealId));\r\n scope.flightCrewMeals.CrewMealsDescriptions[index].HasRating = true;\r\n manageResponseMessage(\"success\", res.message)\r\n }\r\n else {\r\n manageResponseMessage(\"failure\", res.message)\r\n }\r\n }\r\n\r\n function manageResponseMessage(panelToShow, message) {\r\n scope.submitRatingMessage = message;\r\n scope.showPanel = panelToShow;\r\n $timeout(function () { scope.showPanel = \"meals\"; }, 3000);\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: true,\r\n templateUrl: 'views/directives/crewMeals.tpl.html',\r\n scope: {\r\n dutyNo: '@',\r\n dutyDay: '@',\r\n flightId: '@'\r\n },\r\n link: link\r\n }\r\n }\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('eventHistory',eventHistory);\r\n\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name eventHistory\r\n * @restrict E\r\n * @description\r\n * Implementation of eventHistory\r\n * Initialize the Event History of report incidents (mockup view).\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */ \r\nfunction eventHistory() {\r\n\r\n\t\treturn {\r\n\t\t\trestrict: 'E',\r\n templateUrl: 'views/directives/eventHistory.tpl.html',\r\n\t\t}\r\n\t}\r\n\r\n})();\r\n\t","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('flightCrew',flightCrew);\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name flightCrew\r\n * @restrict E\r\n * @description\r\n * Initialize Flight Crew Information\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */ \r\nfunction flightCrew () {\r\n function link(scope, element, attrs){\r\n }\r\n\t\treturn {\r\n\t\t\trestrict: 'E',\r\n\t\t\tterminal: true,\r\n\t\t\ttemplateUrl: \"views/directives/flightCrew.tpl.html\",\r\n\t\t\tscope : {\r\n flight: '='\r\n },\r\n link: link\r\n\t\t}\r\n\t} \r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('flightFooter', flightFooter);\r\n\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name flightFooter\r\n * @restrict E\r\n * @description\r\n * Implementation of FlightFooter\r\n *\r\n * Initialize The flights Footer Template and its Navigation, Sync, Footer Functionality\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function flightFooter(orderByFilter, $location, $sce, $timeout, $interval, $filter, apiUrl, $uibModal, $route, SettingsMain, MemoFactory, MessageFactory, FlightFactory, UserFactory, DataCleanerFactory, CabinReportLocalEditFactory, ReportGuidFactory, SyncLogFactory, CrewRouteFactory, GroundDutyFactory) {\r\n /**\r\n * Initialize flightFooter and events\r\n * @memberof flightFooter\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attrs attribute of this element\r\n */\r\n function link(scope, element, attrs) {\r\n\r\n if (scope.flight) {\r\n var flightId = scope.flight.FlightId;\r\n var state = scope.state;\r\n var report = scope.report;\r\n var flights = getPreviousAndNextFlights(flightId);\r\n var user = UserFactory.getUser();\r\n var delay = 60000;\r\n\r\n var isAssessmentEnabled = SettingsMain.getIsAssessmentEnabled();\r\n\r\n\r\n var showAssessment = isAssessmentEnabled && scope.flight.assessment;\r\n var showFlightReport = scope.flight.LineStatus != 'na';\r\n var hasMultipleReports = showAssessment && !scope.flight.assessment.IsExist && showFlightReport;\r\n\r\n /**\r\n * Find previous,next and current flight of the Route of the selected flight\r\n * @memberof flightFooter\r\n * @param {number} flightId input the Id of a Flight \r\n * @returns {Object} previous,next and current flight\r\n */\r\n function getPreviousAndNextFlights(flightId) {\r\n var nextFlight, previousFlight, currentFlight;\r\n\r\n var flights = FlightFactory.getFlightsByRoute(scope.flight.Route, scope.flight.DutyDate);\r\n\r\n flights = orderByFilter(flights, orderByDate, false);\r\n\r\n function orderByDate(item) {\r\n var date = new Date(item.ScheduledDeparture);\r\n return date;\r\n }\r\n\r\n for (var i = 0; i < flights.length; i++) {\r\n if (flights[i].FlightId == flightId) {\r\n if (i >= 1) {\r\n previousFlight = flights[i - 1];\r\n }\r\n if (i + 1 < flights.length) {\r\n nextFlight = flights[i + 1];\r\n }\r\n currentFlight = flights[i];\r\n }\r\n }\r\n\r\n return {\r\n nextFlight: nextFlight,\r\n previousFlight: previousFlight,\r\n currentFlight: currentFlight\r\n };\r\n }\r\n\r\n /**\r\n * It handles the cabin report when u want to navigate to another view\r\n * @memberof flightFooter\r\n * @param {String} state input the current state (view) \r\n * @param {number} flightId input the Id of a Flight \r\n * @param {Object} report input the cabin report \r\n */\r\n function handleIfReport(state, flightId, report) {\r\n if (state == 'report') {\r\n if (report == null) {\r\n report = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId);\r\n }\r\n var guid = report.ReportGuid;\r\n var status = report.Status;\r\n\r\n // delete the temp report\r\n CabinReportLocalEditFactory.deleteTempReport();\r\n\r\n //reuse guid if this was a new report\r\n if (status == 'pending')\r\n ReportGuidFactory.restoreGuid(report.ReportGuid);\r\n }\r\n }\r\n\r\n /**\r\n * Open the Cabin Report for the selected Flight\r\n * @memberof flightFooter \r\n * @param {number} flightId input the Id of a Flight\r\n */\r\n function openReport(flightId) {\r\n var user = UserFactory.getUser();\r\n var token = '';\r\n if (user != null) {\r\n token = user.token;\r\n token = encodeURIComponent(token);\r\n }\r\n\r\n // load the flight\r\n var flight = FlightFactory.getFlightFromStorage(flightId);\r\n if (flight == null) {\r\n // if not found, also check the local flights\r\n var flight = FlightFactory.getLocalFlightFromStorage(flightId);\r\n if (flight == null)\r\n return;\r\n }\r\n \r\n \r\n\r\n // load the reports\r\n var serverReportForThisUser = flight.getServerCabinReportForUser(user.aimsId);\r\n var serverReportsByAnotherUser = flight.getServerCabinReportsByAnotherUser(user.aimsId);\r\n var localReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId);\r\n\r\n // no stored local report\r\n if (localReport == null) {\r\n // has server report from this user and from other users\r\n if ((serverReportForThisUser != null) && (serverReportsByAnotherUser.length > 0)) {\r\n // show selection dialog\r\n openReportDialog(flightId);\r\n }\r\n // has server report only from this user\r\n else if ((serverReportForThisUser != null) && (serverReportsByAnotherUser.length == 0)) {\r\n $location.path(\"reportsHistory/\" + serverReportForThisUser.ReportId + \"/\" + flightId+\"/Cabin\");\r\n }\r\n // has server report only from other users\r\n else if ((serverReportForThisUser == null) && (serverReportsByAnotherUser.length > 0)) {\r\n // show selection dialog\r\n openReportDialog(flightId);\r\n }\r\n // no server reports, create a new local report directly\r\n else {\r\n $location.path(\"report/new:\" + -1 + \"/\" + flightId);\r\n }\r\n }\r\n // has stored local report\r\n else {\r\n // special case: has server report from this user, and not from\r\n // other users\r\n if ((serverReportForThisUser != null) && (serverReportsByAnotherUser.length == 0)) {\r\n // open the local report for editing\r\n $location.path(\"report/\" + localReport.ReportGuid);\r\n }\r\n // general case: has server report from this user or from other\r\n // users\r\n else if ((serverReportForThisUser != null) || (serverReportsByAnotherUser.length > 0)) {\r\n // show selection dialog\r\n openReportDialog(flightId);\r\n }\r\n // no server reports, open the local report directly\r\n else {\r\n // open the existing report for editing\r\n $location.path(\"report/\" + localReport.ReportGuid);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Open a modal to choose an action when there is already a cabin report from another user\r\n * @memberof flightFooter \r\n * @param {number} flightId input the Id of a Flight\r\n */\r\n function openReportDialog(flightId) {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: './views/Dialogs/dlgOpenReport.html',\r\n controller: 'OpenReportDialogCtrl',\r\n size: 'md',\r\n resolve: {\r\n flightId: function () {\r\n return flightId;\r\n }\r\n }\r\n });\r\n\r\n modalInstance.result.then(function () {}, function () {});\r\n }\r\n\r\n /**\r\n * Open a modal from which u can Logout from the application\r\n * @memberof flightFooter \r\n */\r\n function logout() {\r\n var isSecure = UserFactory.isSecure()\r\n bootbox.dialog({\r\n message: (isSecure ?\r\n \"Due to the fact that you are working over a public computer, all stored data will be deleted on logout!

\" :\r\n \"You will be able to login again into the same account, even if there is no internet access.

\") +\r\n \"Please confirm that you wish to log out.\",\r\n title: \"User Logout\",\r\n buttons: {\r\n cancel: {\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function () {}\r\n },\r\n logout: {\r\n label: \"Logout\",\r\n className: \"btn-warning\",\r\n callback: function () {\r\n UserFactory.clearActiveUser();\r\n if (isSecure) DataCleanerFactory.deleteAllData();\r\n\r\n UserFactory.azSignOut();\r\n \r\n location.reload(true);\r\n // need to reload, in order for the\r\n // browser to check the cache.manifest\r\n // and discover any changes\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Redirects to Reset Device View\r\n * @memberof flightFooter \r\n */\r\n function resetDevice() {\r\n SettingsMain.setEditingPage(null);\r\n $location.path(\"/reset\");\r\n }\r\n\r\n /**\r\n * Open a modal from which you can delete all available reports\r\n * @memberof flightFooter \r\n * @method\r\n */\r\n function deleteAllReports() {\r\n bootbox.dialog({\r\n message: \"Use this process to clear your device from all locally stored Cabin Reports, in order to save up space, when available storage space is not sufficient for the application to function properly.

\" +\r\n \"

ATTENTION

\" +\r\n \"This action will delete all Cabin Reports from your device, including draft and completed ones not sent to the server.\",\r\n title: \"Application Logs Reset\",\r\n buttons: {\r\n cancel: {\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function () {}\r\n },\r\n danger: {\r\n label: \"Delete All Cabin Reports\",\r\n className: \"btn-danger\",\r\n callback: function () {\r\n DataCleanerFactory.deleteAllReports();\r\n $route.reload();\r\n bootbox.alert(\"All Cabin Reports have been successfully deleted.\", function () {});\r\n }\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Navigate to Calendar View\r\n * @memberof flightFooter \r\n */\r\n function gotoCalendar() {\r\n handleIfReport(state, flightId, report);\r\n\r\n SettingsMain.setEditingPage(null);\r\n // go to dashboard\r\n $location.path(\"/\");\r\n }\r\n /**\r\n * Navigate to Bucket Calendar View\r\n * @memberof flightFooter \r\n */\r\n function gotoBucketCalendar() {\r\n SettingsMain.setEditingPage(null);\r\n $location.path('/bucket');\r\n }\r\n /**\r\n * Navigate to FAQs View\r\n * @memberof flightFooter \r\n */\r\n function gotoFAQs() {\r\n SettingsMain.setEditingPage(null);\r\n $location.path('/faqs');\r\n }\r\n /**\r\n * Navigate to Roster Requests\r\n * @memberof flightFooter \r\n */\r\n function gotoRequests() {\r\n SettingsMain.setEditingPage(null);\r\n $location.path('/rosterRequests');\r\n }\r\n\r\n /**\r\n * Navigate to Selected Flight Information View\r\n * @param {number} flightId input the Id of a Flight\r\n * @memberof flightFooter \r\n */\r\n function gotoFlight(flightId) {\r\n SettingsMain.setEditingPage(null);\r\n handleIfReport(state, flightId, report);\r\n $location.path('/flightinfo/' + flightId);\r\n }\r\n\r\n /**\r\n * Navigate to Messages View\r\n * @memberof flightFooter \r\n */\r\n function gotoMessageLibrary() {\r\n handleIfReport(state, flightId, report);\r\n $location.path('/messages');\r\n }\r\n\r\n /**\r\n * Navigate to the Current Flight's Information View\r\n * @memberof flightFooter \r\n */\r\n function gotoFlightInfo() {\r\n gotoFlight(flightId);\r\n }\r\n\r\n /**\r\n * Navigate to Submit ticket view\r\n * @memberof flightFooter \r\n */\r\n function gotoTicket() {\r\n // go to Submit ticket view\r\n $location.path(\"/ticket\");\r\n }\r\n \r\n function goToSafetyReport(flightId) {\r\n $location.path('/safetyreport/cabincrewreport/' + flightId);\r\n }\r\n\r\n function goToFatigueReport(flightId) {\r\n $location.path('/safetyreport/fatiguereport/' + flightId);\r\n }\r\n\r\n /**\r\n * Open current's Flight Cabin Report\r\n * @memberof flightFooter \r\n */\r\n function openCabinReport() {\r\n SettingsMain.setEditingPage(null);\r\n openReport(flightId);\r\n }\r\n\r\n /**\r\n * Navigate to the Current Flight's Pax Information View\r\n * @memberof flightFooter \r\n */\r\n function gotoPaxInfo() {\r\n SettingsMain.setEditingPage(null);\r\n handleIfReport(state, flightId, report);\r\n $location.path('/pax/' + flightId);\r\n }\r\n\r\n /**\r\n * Open current's Flight Cabin Crew Feedback Report\r\n * @memberof flightFooter \r\n */\r\n function openAssessment() {\r\n SettingsMain.setEditingPage(null);\r\n $location.path(\"assessment/\" + flightId);\r\n }\r\n\r\n /**\r\n * Navigate to Memos Library\r\n * @memberof flightFooter \r\n */\r\n function gotoMemosLibrary() {\r\n SettingsMain.setEditingPage(null);\r\n handleIfReport(state, flightId, report);\r\n $location.path('/memos');\r\n }\r\n\r\n //todo:: clean up\r\n // /**\r\n // * Get the latest Pax and Gate Informations\r\n // * @memberof flightFooter \r\n // */\r\n // function SynchPaxAndGates() {\r\n // var modalInstance = $uibModal.open({\r\n // templateUrl: 'views/Dialogs/dlgLightSync.html',\r\n // controller: 'SyncPaxCtrl',\r\n // size: 'md',\r\n // backdrop: 'static',\r\n // keyboard: false,\r\n // resolve: {\r\n // flightId: function () {\r\n // return flightId;\r\n // },\r\n // }\r\n // })\r\n\r\n // modalInstance.result.then(function () {\r\n // scope.lastSync = new Date().getTime();\r\n // }, function () {});\r\n // }\r\n\r\n /**\r\n * Opens refresh modal for results\r\n */\r\n function RefreshRoute(){\r\n var dutyNo = scope.flight.DutyNo;\r\n var dutyDay = scope.flight.DutyDay;\r\n var crewRouteDuty = CrewRouteFactory.getCrewRouteFromStorage(dutyNo, dutyDay);\r\n var groundDuties = GroundDutyFactory.getGroundDutiesByDutyNo(dutyNo, dutyDay);\r\n if(groundDuties.length > 0){ //there are ground duties in this crew route\r\n angular.forEach(groundDuties, function(groundDuty)\r\n {\r\n groundDuty.DutyType = \"Ground\";\r\n groundDuty.Start = groundDuty.DutyBegin;\r\n });\r\n }\r\n \r\n var flights = FlightFactory.getFlightsByDutyNo(dutyNo, dutyDay);\r\n if(flights.length > 0){ //there are flights in this crew route\r\n angular.forEach(flights, function(flight)\r\n {\r\n flight.DutyType = \"Flight\";\r\n flight.Start = flight.ScheduledDeparture;\r\n });\r\n }\r\n \r\n var crewRoute = groundDuties.concat(flights);\r\n crewRoute = $filter('orderBy')(crewRoute, 'Start', false);\r\n\r\n\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/CrewRoute/dlgCrewRouteRefresh.html',\r\n controller: 'CrewRouteRefreshModalCtrl',\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n crewroute: function () { return crewRoute}, \r\n crewRouteDuty: function () { return crewRouteDuty },\r\n dutyNo: function () { return Number(dutyNo) },\r\n dutyDay: function () { return Number(dutyDay) },\r\n forCurrentDay: function() { return scope.flight.FlightDate},\r\n }\r\n });\r\n \r\n modalInstance.result.then(function (transferData) {\r\n scope.lastSync = new Date().getTime();\r\n if(transferData.sync){\r\n SyncLogFactory.forceSync();\r\n $location.path(\"/\"); //crew route has significantly changed\r\n }\r\n else if(transferData.refresh){\r\n $route.reload(); //crew route was updated\r\n }\r\n });\r\n }\r\n\r\n\r\n /**\r\n * Show Popover that advices User to sync so he can get the latest Pax and Gate Informations\r\n * @memberof flightFooter \r\n */\r\n function showSyncPopover() {\r\n var firstSyncWarning = departure - 4500000; //75 mintes before takeoff\r\n var secondSyncWarning = departure - 600000; //10 minutes before takeoff\r\n var now = new Date().getTime();\r\n var lastSync = scope.lastSync;\r\n\r\n if ((now > firstSyncWarning && now < secondSyncWarning && (!lastSync || lastSync < firstSyncWarning)) || (now > secondSyncWarning && now < departure && (!lastSync || lastSync < secondSyncWarning))) {\r\n scope.enableSyncPopover = true;\r\n }\r\n }\r\n\r\n /**\r\n * Calculate the time difference of pax info list from now\r\n * @memberof flightFooter \r\n */\r\n function returnTimeDiff() {\r\n //time difference in minutes from: now and pax info list date\r\n scope.paxTimeDiffInMins = Math.round((new Date().getTime() - new Date(scope.paxInfo.LastRun).getTime()) / 60000);\r\n }\r\n\r\n var reportsPopoverTemplateUrl = 'views/directives/reportsPopover.tpl.html';\r\n\r\n\r\n if (state == 'pax' || state == 'flight' && scope.paxInfo) {\r\n var now = new Date().getTime();\r\n var departure = new Date(scope.flight.ScheduledDeparture).getTime();\r\n\r\n if (departure < now) {\r\n var openSyncPopover = $interval(showSyncPopover, delay);\r\n }\r\n }\r\n\r\n if (state == 'pax' || state == 'flight') {\r\n if (scope.paxInfo && (new Date(scope.flight.ScheduledDeparture).getTime() > new Date().getTime())) {\r\n returnTimeDiff();\r\n var showTimeDiff = $interval(returnTimeDiff, delay);\r\n }\r\n }\r\n\r\n scope.showAssessment = showAssessment;\r\n scope.showFlightReport = showFlightReport;\r\n scope.hasMultipleReports = hasMultipleReports;\r\n scope.reportsPopoverTemplateUrl = reportsPopoverTemplateUrl;\r\n scope.gotoFAQs = gotoFAQs;\r\n scope.gotoRequests = gotoRequests;\r\n scope.gotoFlight = gotoFlight;\r\n scope.previousFlight = flights.previousFlight;\r\n scope.nextFlight = flights.nextFlight;\r\n scope.gotoBucketCalendar = gotoBucketCalendar;\r\n scope.gotoCalendar = gotoCalendar;\r\n scope.gotoFlightInfo = gotoFlightInfo;\r\n scope.openCabinReport = openCabinReport;\r\n scope.logout = logout;\r\n scope.resetDevice = resetDevice;\r\n scope.deleteAllReports = deleteAllReports;\r\n scope.gotoMessageLibrary = gotoMessageLibrary;\r\n scope.gotoPaxInfo = gotoPaxInfo;\r\n scope.gotoMemosLibrary = gotoMemosLibrary;\r\n scope.RefreshRoute = RefreshRoute;\r\n scope.showPopover = false;\r\n scope.showMobileMenu = false;\r\n scope.userPosition = user.position;\r\n scope.openAssessment = openAssessment;\r\n scope.gotoTicket = gotoTicket;\r\n scope.goToSafetyReport = goToSafetyReport;\r\n scope.goToFatigueReport = goToFatigueReport;\r\n\r\n scope.syncWarning = $sce.trustAsHtml('
You are strongly advised to sync your device.
');\r\n scope.enableSyncPopover = false;\r\n scope.lastSync = null;\r\n\r\n element.on('$destroy', function () {\r\n $interval.cancel(openSyncPopover);\r\n $interval.cancel(showTimeDiff);\r\n });\r\n\r\n }\r\n }\r\n\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: true,\r\n templateUrl: \"views/Flight/footer.tpl.html\",\r\n scope: false,\r\n link: link\r\n }\r\n\r\n }\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('flightHeader',flightHeader);\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name flightHeader\r\n * @restrict E\r\n * @description\r\n * Implementation of flightHeader\r\n * Initialize the template of the header while you are in the Flight Level\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */ \r\nfunction flightHeader () {\r\n\t\treturn {\r\n\t\t\trestrict: 'E',\r\n\t\t\tterminal: true,\r\n\t\t\ttemplateUrl: \"views/Flight/header.tpl.html\",\r\n\t\t\tscope: false\r\n\t\t}\r\n\t} \r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('groundCrew',groundCrew);\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name groundCrew\r\n * @restrict E\r\n * @description\r\n * Initialize Trainer and Trainee Info\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */ \r\nfunction groundCrew () {\r\n function link(scope, element, attrs){\r\n scope.groundDuty = scope.duty;\r\n scope.toggleCrewList = toggleCrewList\r\n\r\n scope.groundDuty.Trainees.forEach(function(relatedTrainees){\r\n relatedTrainees.isCollapsed = false;\r\n relatedTrainees.dynamicSize = 10;\r\n });\r\n\r\n /**\r\n * @memberof GroundDutyCtrl\r\n * @name toggleCrewList\r\n * @description \r\n * Οnly show the first 10 trainees - if more then toggle\r\n */\r\n function toggleCrewList(relatedTrainees){\r\n relatedTrainees.isCollapsed = !relatedTrainees.isCollapsed;\r\n\r\n if(relatedTrainees.isCollapsed) relatedTrainees.dynamicSize = relatedTrainees.CrewMembers.length;\r\n else relatedTrainees.dynamicSize = 10;\r\n }\r\n\r\n }\r\n\t\treturn {\r\n\t\t\trestrict: 'E',\r\n\t\t\tterminal: true,\r\n\t\t\ttemplateUrl: \"views/directives/groundCrew.tpl.html\",\r\n\t\t\tscope : {\r\n duty: '='\r\n },\r\n link: link\r\n\t\t}\r\n\t} \r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('groundHeader', groundHeader);\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name groundHeader\r\n * @restrict E\r\n * @description\r\n * Implementation of groundHeader (appears in groundDuty-info view)\r\n * Initialize the template of the header while you are in the Ground Duty Level\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */ \r\n \r\nfunction groundHeader () {\r\n\t\treturn {\r\n\t\t\trestrict: 'E',\r\n\t\t\tterminal: true,\r\n\t\t\ttemplateUrl: \"views/GroundDuty/header.tpl.html\",\r\n\t\t\tscope: false\r\n\t\t}\r\n\t} \r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('groundInfo',groundInfo);\r\n\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name groundInfo\r\n * @restrict EA\r\n * @description\r\n * Implementation of groundInfo\r\n *\r\n * Initialize the ground information (Contacts,Hotels)\r\n * @attr {String} station The name of the station to get the ground information.\r\n * @example\r\n * Usage:\r\n *
\r\n * @ngInject\r\n */ \r\nfunction groundInfo(AirportContactFactory,AirportHotelFactory) {\r\n\r\n /**\r\n * Calculates distinct HotelTypes (used for filtering results)\r\n * @memberof AirportHotelCtrl\r\n * @param {array} All the airport Hotels (object which containts Hotels property)\r\n * @return {array} The distinct HotelTypes as an array of strings\r\n */\r\n function findDistinctHotelTypes(items){\r\n var unique = {};\r\n var distinct = [];\r\n for( var i in items ){\r\n if( items[i].Name && typeof(unique[items[i].Name]) == \"undefined\"){\r\n distinct.push(items[i].Name);\r\n }\r\n unique[items[i].Name] = 0;\r\n }\r\n return distinct;\r\n }\r\n\r\n /**\r\n * Used to properly display some Hotel Types, eg nulls\r\n * @memberof AirportHotelCtrl\r\n * @param {string} The Hotel type to examine and \"fix\"\r\n * @return {string} The \"fixed\" string for the given Hotel type (maybe the same as the input value if no fix is needed)\r\n */\r\n function printHotelType(HotelType){\r\n if (!HotelType || HotelType == ''){\r\n console.log(HotelType);\r\n HotelType = '-no Hotel type-';\r\n }\r\n \r\n return HotelType;\r\n }\r\n \r\n /**\r\n * Calculates distinct ContactTypes (used for filtering results)\r\n * @memberof AirportContactCtrl\r\n * @param {array} All the airport contacts (object which containts Contacts property)\r\n * @return {array} The distinct ContactTypes as an array of strings\r\n */\r\n function findDistinctContactTypes(items){\r\n var unique = {};\r\n var distinct = [];\r\n for( var i in items ){\r\n if(items[i].ContactType && typeof(unique[items[i].ContactType]) == \"undefined\"){\r\n distinct.push(items[i].ContactType);\r\n }\r\n unique[items[i].ContactType] = 0;\r\n }\r\n return distinct;\r\n }\r\n \r\n /**\r\n * Used to properly display some Contact Types, eg nulls\r\n * @memberof AirportContactCtrl\r\n * @param {string} The contact type to examine and \"fix\"\r\n * @return {string} The \"fixed\" string for the given contact type (maybe the same as the input value if no fix is needed)\r\n */\r\n function printContactType(contactType){\r\n if (!contactType || contactType == '')\r\n return '-no contact type-';\r\n return contactType;\r\n }\r\n \r\n\t\r\n\t\treturn {\r\n\t\t\trestrict: 'EA',\r\n\t\t\tterminal: true,\r\n templateUrl: 'views/directives/groundInfo.tpl.html',\r\n\t\t\tscope : true,\r\n link: function ($scope, element, attrs) {\r\n var stations = attrs.stations? attrs.stations.split(\",\") : [];\r\n $scope.stationsInfo = []\r\n $scope.filterHotelType = '';\r\n $scope.filterContactType = '';\r\n \r\n //scope methods\r\n $scope.printHotelType = printHotelType;\r\n $scope.printContactType = printContactType;\r\n $scope.showInfo = showInfo;\r\n \r\n angular.forEach(stations,function(station){\r\n var stationInfo = {};\r\n \r\n var flightDate = $scope.flight && $scope.flight.FlightDate ? $scope.flight.FlightDate : null;\r\n var contactInfo = AirportContactFactory.getAirportContacts(station);\r\n stationInfo.Contacts = contactInfo ? contactInfo.Contacts : [];\r\n stationInfo.ContactTypes = findDistinctContactTypes(stationInfo.Contacts)\r\n \r\n var hotelInfo = AirportHotelFactory.getAirportHotels(station, flightDate);\r\n stationInfo.Hotels = hotelInfo ? hotelInfo.Hotels : [];\r\n stationInfo.HotelTypes = findDistinctHotelTypes(stationInfo.Hotels);\r\n \r\n stationInfo.ActiveHotels = false;\r\n stationInfo.ActiveContacts = false;\r\n stationInfo.ActiveGeneralInfo= false;\r\n \r\n stationInfo.Name = station;\r\n if(stationInfo.Hotels.length>0 || stationInfo.Contacts.length>0){\r\n $scope.stationsInfo.push(stationInfo);\r\n }\r\n \r\n });\r\n \r\n var oldViewStation = '';\r\n var oldViewType = '';\r\n \r\n function showInfo(station,type){\r\n \r\n angular.forEach($scope.stationsInfo,function(stationInfo){\r\n if(stationInfo.Name == station.Name){\r\n if(type=='Hotels'){\r\n stationInfo.ActiveHotels = !stationInfo.ActiveHotels;\r\n stationInfo.ActiveContacts = false;\r\n stationInfo.ActiveGeneralInfo=false;\r\n }else if(type=='Contacts'){\r\n stationInfo.ActiveContacts = !stationInfo.ActiveContacts;\r\n stationInfo.ActiveHotels = false;\r\n stationInfo.ActiveGeneralInfo=false;\r\n }else if(type=='General'){\r\n stationInfo.ActiveGeneralInfo=!stationInfo.ActiveGeneralInfo;\r\n stationInfo.ActiveHotels = false;\r\n stationInfo.ActiveContacts = false;\r\n }\r\n }else{\r\n stationInfo.ActiveHotels = false;\r\n stationInfo.ActiveContacts = false;\r\n stationInfo.ActiveGeneralInfo=false;\r\n }\r\n })\r\n \r\n }\r\n\t\t}\r\n\t}\r\n}\r\n})();\r\n\t","(function() {\r\n 'use strict';\r\n a3_cabin_reports.directive('groundServices', groundServices);\r\n\r\n/**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name groundServices\r\n * @restrict E\r\n * @description\r\n * Implementation of ground services \r\n *\r\n * Display the ground services\r\n * @attr {String} arrival The flight arrival station.\r\n * @attr {String} departure The flight departure station.\r\n * @attr {String} flight-id The flight id.\r\n * @example\r\n * Usage:\r\n * \r\n * \r\n * @ngInject\r\n */ \r\nfunction groundServices(GroundServicesFactory, CabinReportLocalEditFactory, CabinReportLocalEditCreatorFactory, FlightFactory, $sce) {\r\n\r\n /**\r\n * Initialize groundServices\r\n * @memberof groundServices\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\r\n function link(scope, element, attributes){\r\n scope.togglePanel = togglePanel;\r\n scope.flight = FlightFactory.getFlightFromTotalFlights(scope.flightId);\r\n scope.isInFinalState = isInFinalState;\r\n scope.saveNewUsedState = saveNewUsedState;\r\n scope.DepartureGroundServices = [];\r\n scope.ArrivalGroundServices = [];\r\n scope.popoverInfo = {\r\n title: $sce.trustAsHtml(' Info'),\r\n contentHtml: $sce.trustAsHtml('
Contracted Services' + \r\n '
Non Contracted Services' +\r\n '
')\r\n };\r\n var report = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(scope.flightId);\r\n\r\n if (report == null){\r\n if (scope.departure){\r\n scope.DepartureGroundServices = GroundServicesFactory.getGroundServicesByStation(scope.departure);\r\n }\r\n // if (scope.arrival){\r\n // scope.ArrivalGroundServices = GroundServicesFactory.getGroundServicesByStation(scope.arrival);\r\n // }\r\n }\r\n else {\r\n report = CabinReportLocalEditFactory.checkForNewGroundServices(report);\r\n if (scope.departure){\r\n scope.DepartureGroundServices = report.DepartureGroundServices;\r\n }\r\n // if (scope.arrival){\r\n // scope.ArrivalGroundServices = report.ArrivalGroundServices;\r\n // }\r\n }\r\n\r\n\r\n /**\r\n * Check if the report is in a final state so that we cant edit any more\r\n * @memberof groundServices\r\n * @returns {boolean} true if final, false otherwise\r\n */\r\n function isInFinalState(){\r\n var isInFinalState = ((scope.flight.LineStatus === 'na') ||\r\n (scope.flight.LineStatus === 'stored') ||\r\n (scope.flight.LineStatus === 'storedotheruser') ||\r\n (scope.flight.LineStatus === 'stored+otheruser') ||\r\n (scope.flight.LineStatus === 'synched') ||\r\n (scope.flight.LineStatus === 'synchedotheruser'));\r\n return isInFinalState;\r\n }\r\n\r\n /**\r\n * When a ground service usage is toggled on or off,\r\n * create the report if it doesnt exist\r\n * or just save the changes\r\n * @memberof groundServices\r\n */\r\n function saveNewUsedState() {\r\n //if report is pending, it doesnt exist yet. create it\r\n if (scope.flight.LineStatus === 'pending' || scope.flight.LineStatus === 'pendingoverdue'){\r\n report = CabinReportLocalEditCreatorFactory.createNewLocalReportForFlight(scope.flightId); \r\n if (scope.departure){\r\n report.DepartureGroundServices = scope.DepartureGroundServices;\r\n }else{\r\n report.DepartureGroundServices=[];\r\n }\r\n // if (scope.arrival){\r\n // report.ArrivalGroundServices = scope.ArrivalGroundServices;\r\n // }else{\r\n // report.ArrivalGroundServices = [];\r\n // }\r\n report.Status = 'draft';\r\n report.saveReport();\r\n FlightFactory.updateFlightFromReport(report);\r\n }\r\n\r\n CabinReportLocalEditFactory.setCabinReportToStorage(report);\r\n }\r\n\r\n //TODO : find a more angular way (EPAP)\r\n /**\r\n * toggle Panel\r\n * @memberof groundServices\r\n * @param {number} panelId\r\n */\r\n function togglePanel(panelId) {\r\n $('#' + panelId).toggle();\r\n }\r\n }\r\n \r\n return {\r\n\t\t\trestrict: 'E',\r\n\t\t\tterminal: true,\r\n\t\t\ttemplateUrl: 'views/directives/groundServices.tpl.html',\r\n\t\t\tscope: {\r\n arrival: '@',\r\n departure: '@',\r\n flightId: '@'\r\n },\r\n link: link\r\n }\r\n}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('issues',issues);\r\n\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name issues\r\n * @restrict EA\r\n * @description\r\n * Implementation of issues\r\n *\r\n * Initialize the issues telplates for the cabin report form according to their type\r\n * @attr {String} type The name of the type to initialize the according Issue template.\r\n * @example\r\n * Usage:\r\n *
\r\n * @ngInject\r\n */ \r\nfunction issues() {\r\n\r\n\t\tfunction templateUrl(type){\r\n\t\t\tvar template='views/reportItems/empty.html';\r\n\t\t\tif (type=='bar'){\r\n\t\t\t\ttemplate='views/Report/bar.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='medicalincidents'){\r\n\t\t\t\ttemplate='views/Report/medicalIncidents.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='securitycheck'){\r\n\t\t\t\ttemplate='views/Report/securityCheck.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='specialmeals'){\r\n\t\t\t\ttemplate='views/Report/specialMeals.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='supplies'){\r\n\t\t\t\ttemplate='views/Report/supplies.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='travelvalues'){\r\n\t\t\t\ttemplate='views/Report/travelValues.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='um'){\r\n\t\t\t\ttemplate='views/Report/um.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='various'){\r\n\t\t\t\ttemplate='views/Report/various.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='wateruplift'){\r\n\t\t\t\ttemplate='views/Report/waterUplift.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='groundservices'){\r\n\t\t\t\ttemplate='views/Report/groundServices.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='changedseats'){\r\n\t\t\t\ttemplate='views/Report/changedSeats.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='upgd'){\r\n\t\t\t\ttemplate='views/Report/upgd.tpl.html';\r\n\t\t\t}\r\n\t\t\telse if(type=='incompleteServices'){\r\n\t\t\t\ttemplate='views/Report/incompleteServices.tpl.html';\r\n\t\t\t}\r\n\r\n\t\t\t// else if(type=='boardingtimes'){\r\n\t\t\t// \ttemplate='views/Report/boardingTimes.tpl.html';\r\n\t\t\t// }\r\n\t\t\t// else if(type=='disembarkationtimes'){\r\n\t\t\t// \ttemplate='views/Report/disembarkationTimes.tpl.html';\r\n\t\t\t// }\r\n\r\n\t\t\telse if(type=='luggage'){\r\n\t\t\t\ttemplate='views/Report/luggage.tpl.html';\r\n\t\t\t}\r\n\t\t\treturn template;\r\n\t\t}\r\n\t\r\n\t\treturn {\r\n\t\t\trestrict: 'EA',\r\n\t\t\tterminal: false,\r\n\t\t\ttemplateUrl: function (element, attrs ) { \r\n\t\t\t\t\treturn templateUrl(attrs.type) ;\r\n\t\t\t},\r\n\t\t\tscope: false\r\n\t\t}\r\n\t}\r\n\r\n})();\r\n\t","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.directive('mainFooter', mainFooter);\r\n\r\n\t/**\r\n\t * @memberof CabinReports\r\n\t * @ngdoc directive\r\n\t * @name mainFooter\r\n\t * @restrict E\r\n\t * @description\r\n\t * Implementation of mainFooter\r\n\t * Initialize The main Footer Template and its Navigation, Sync, Footer Functionality\r\n\t * @example\r\n\t * Usage:\r\n\t * \r\n\t * @ngInject \r\n\t */\r\n\tfunction mainFooter($location, SettingsMain, UserFactory, $uibModal, MessageFactory, DataCleanerFactory, $route, MemoFactory, FaqFactory, RequestFactory, $sce, $timeout, FlightFactory, LeaveRequestFactory, PassengerMealServiceFactory) {\r\n\t\t/**\r\n\t\t * Initialize mainFooter and events\r\n\t\t * @memberof mainFooter\r\n\t\t * @param {service} scope the scope of this element\r\n\t\t * @param {service} element element that this direcive is assigned to\r\n\t\t * @param {service} attrs attribute of this element\r\n\t\t */\r\n\t\tfunction link(scope, element, attrs) {\r\n\r\n\t\t\tvar messagesCount = 0;\r\n\t\t\tvar messages = [];\r\n\t\t\tvar unreadMessagesCount = 0;\r\n\t\t\tvar memosCount = 0;\r\n\t\t\tvar memos = [];\r\n\t\t\tvar faqs = [];\r\n\t\t\tvar newFAQCount = 0;\r\n\t\t\tvar updatedFAQCount = 0;\r\n\r\n\t\t\t/**\r\n\t\t\t * Open a modal from which u can Logout from the application\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t */\r\n\t\t\tfunction logout() {\r\n\t\t\t\tvar isSecure = UserFactory.isSecure()\r\n\t\t\t\tbootbox.dialog({\r\n\t\t\t\t\tmessage: (isSecure ?\r\n\t\t\t\t\t\t\"Due to the fact that you are working over a public computer, all stored data will be deleted on logout!

\" :\r\n\t\t\t\t\t\t\"You will be able to login again into the same account, even if there is no internet access.

\") +\r\n\t\t\t\t\t\t\"Please confirm that you wish to log out.\",\r\n\t\t\t\t\ttitle: \"User Logout\",\r\n\t\t\t\t\tbuttons: {\r\n\t\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\tlogout: {\r\n\t\t\t\t\t\t\tlabel: \"Logout\",\r\n\t\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\t\tUserFactory.clearActiveUser();\r\n\t\t\t\t\t\t\t\tif (isSecure) DataCleanerFactory.deleteAllData();\r\n\r\n\t\t\t\t\t\t\t\tUserFactory.azSignOut();\r\n\t\t\t\t\t\t\t\tlocation.reload(true);\r\n\t\t\t\t\t\t\t\t// need to reload, in order for the\r\n\t\t\t\t\t\t\t\t// browser to check the cache.manifest\r\n\t\t\t\t\t\t\t\t// and discover any changes\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Redirects to Reset Device View\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t */\r\n\t\t\tfunction resetDevice() {\r\n\t\t\t\t$location.path(\"/reset\");\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Open a modal from which you can delete all available reports\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t * @method\r\n\t\t\t */\r\n\t\t\tfunction deleteAllReports() {\r\n\t\t\t\tbootbox.dialog({\r\n\t\t\t\t\tmessage: \"Use this process to clear your device from all locally stored Cabin Reports, in order to save up space, when available storage space is not sufficient for the application to function properly.

\" +\r\n\t\t\t\t\t\t\"

ATTENTION

\" +\r\n\t\t\t\t\t\t\"This action will delete all Cabin Reports from your device, including draft and completed ones not sent to the server.\",\r\n\t\t\t\t\ttitle: \"Application Logs Reset\",\r\n\t\t\t\t\tbuttons: {\r\n\t\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\tdanger: {\r\n\t\t\t\t\t\t\tlabel: \"Delete All Cabin Reports\",\r\n\t\t\t\t\t\t\tclassName: \"btn-danger\",\r\n\t\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\t\tDataCleanerFactory.deleteAllReports();\r\n\t\t\t\t\t\t\t\t$route.reload();\r\n\t\t\t\t\t\t\t\tbootbox.alert(\"All Cabin Reports have been successfully deleted.\", function () { });\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Navigate to Calendar View\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t */\r\n\t\t\tfunction gotoCalendar() {\r\n\t\t\t\tSettingsMain.setEditingPage(null);\r\n\t\t\t\t// go to dashboard\r\n\t\t\t\t$location.path(\"/\");\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Navigate to Submit ticket view\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t */\r\n\t\t\tfunction gotoTicket() {\r\n\t\t\t\t// go to Submit ticket view\r\n\t\t\t\t$location.path(\"/ticket\");\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Navigate to Messages View\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t */\r\n\t\t\tfunction gotoMessageLibrary() {\r\n\t\t\t\t$location.path('/messages');\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Navigate to Memos Library\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t */\r\n\t\t\tfunction gotoMemos() {\r\n\t\t\t\t$location.path('/memos');\r\n\t\t\t}\r\n\t\t\t/**\r\n\t\t\t\t* Navigate to Bucket\r\n\t\t\t\t* @memberof mainFooter \r\n\t\t\t\t*/\r\n\t\t\tfunction gotoBucketCalendar() {\r\n\t\t\t\t$location.path('/bucket');\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Navigate to FAQs View\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t */\r\n\t\t\tfunction gotoFAQs() {\r\n\t\t\t\t$location.path('/faqs');\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Navigate to Roster Requests View\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t */\r\n\t\t\tfunction gotoRequests() {\r\n\t\t\t\t$location.path(\"/rosterRequests\");\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Navigate to FAQs View\r\n\t\t\t * @memberof mainFooter \r\n\t\t\t */\r\n\t\t\tfunction gotoLeaveRequests() {\r\n\t\t\t\t$location.path('/leaverequest');\r\n\t\t\t}\r\n\r\n\t\t\tfunction gotoMealLibrary() {\r\n\t\t\t\t$location.path('/mealLibrary');\r\n\t\t\t}\r\n\r\n\t\t\t/**\r\n\t\t\t * Open the \"Search Flight Info\" Modal\r\n\t\t\t * @memberof CalendarCtrl\r\n\t\t\t */\r\n\t\t\tfunction openSearchFlightsModal() {\r\n\t\t\t\tvar modalInstance = $uibModal.open({\r\n\t\t\t\t\ttemplateUrl: './views/SearchFlights/dlgSearchFlights.html',\r\n\t\t\t\t\tcontroller: 'SearchFlightsCtrl',\r\n\t\t\t\t\tsize: 'md',\r\n\t\t\t\t\tbackdrop: 'static',\r\n\t\t\t\t\tkeyboard: false\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\r\n\t\t\tmessages = MessageFactory.getMessagesFromStorage();\r\n\t\t\tmessagesCount = messages.length;\r\n\t\t\tfor (var i = 0; i < messages.length; i++) {\r\n\t\t\t\tif (messages[i].ReadDt == null) {\r\n\t\t\t\t\tunreadMessagesCount++\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tMemoFactory.getNotHiddenMemos(function (results) {\r\n\t\t\t\tscope.memosCount = results.length;\r\n\t\t\t});\r\n\r\n\t\t\tfaqs = FaqFactory.getFAQsFromStorage();\r\n\t\t\tfor (var i = 0; i < faqs.length; i++) {\r\n\t\t\t\tif (faqs[i].newItems) {\r\n\t\t\t\t\tnewFAQCount += faqs[i].newItems;\r\n\t\t\t\t}\r\n\t\t\t\tif (faqs[i].updatedItems) {\r\n\t\t\t\t\tupdatedFAQCount += faqs[i].updatedItems;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tscope.messagesCount = messagesCount;\r\n\t\t\tscope.unreadMessagesCount = unreadMessagesCount;\r\n\t\t\tscope.logout = logout;\r\n\t\t\tscope.resetDevice = resetDevice;\r\n\t\t\tscope.deleteAllReports = deleteAllReports;\r\n\t\t\tscope.gotoMessageLibrary = gotoMessageLibrary;\r\n\t\t\tscope.gotoMemos = gotoMemos;\r\n\t\t\tscope.gotoBucketCalendar = gotoBucketCalendar;\r\n\t\t\tscope.memosCount = memosCount;\r\n\t\t\tscope.gotoFAQs = gotoFAQs;\r\n\t\t\tscope.gotoRequests = gotoRequests;\r\n\t\t\tscope.gotoLeaveRequests = gotoLeaveRequests;\r\n\t\t\tscope.newFAQCount = newFAQCount;\r\n\t\t\tscope.updatedFAQCount = updatedFAQCount;\r\n\t\t\tscope.gotoCalendar = gotoCalendar;\r\n\t\t\tscope.showPopover = false;\r\n\t\t\tscope.gotoTicket = gotoTicket;\r\n\t\t\tscope.leaveRequestInformation = LeaveRequestFactory.getLeaveRequestInformation();\r\n\t\t\tscope.openSearchFlightsModal = openSearchFlightsModal;\r\n\t\t\tscope.gotoMealLibrary = gotoMealLibrary;\r\n\t\t}\r\n\r\n\t\treturn {\r\n\t\t\trestrict: 'E',\r\n\t\t\tterminal: true,\r\n\t\t\ttemplateUrl: \"views/Main/footer.tpl.html\",\r\n\t\t\tscope: false,\r\n\t\t\tlink: link\r\n\t\t}\r\n\t}\r\n\r\n})();","(function () {\r\n\r\n a3_cabin_reports.directive('memosByCategory', memosByCategory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name memosByCategory\r\n * @restrict E\r\n * @description\r\n * Implementation of memosByCategory\r\n * Initialize the panels with memos group by category.\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function memosByCategory(MemoFactory, MemoImagesFactory, $uibModal, DataCleanerFactory, GroundDutyFactory, FlightFactory) {\r\n function link($scope, attrs) {\r\n $scope.togglePanel = togglePanel;\r\n var Id = $scope.id;\r\n \r\n\r\n /**\r\n * toggle Panel\r\n * @memberof memosByCategory\r\n * @param {number} panelId\r\n */\r\n function togglePanel(panelId) {\r\n $('#' + panelId).toggle();\r\n }\r\n\r\n //Initialize Memos\r\n if($scope.type == \"duty\" || $scope.type == \"d\"){\r\n MemoFactory.getMemosForCrewRoute(Id, $scope.day, function (results) {\r\n $scope.memos = filterMemos(results);\r\n });\r\n }\r\n else if($scope.type == \"ground\" || $scope.type == \"g\"){\r\n MemoFactory.getMemosForGroundDuty(Id, function (results) {\r\n $scope.memos = filterMemos(results);\r\n });\r\n }\r\n //(attrs.type == \"flight\" || attrs.type == \"f\") default Flight type\r\n else{\r\n MemoFactory.getMemosForFlight(Id, function (results) {\r\n $scope.memos = filterMemos(results);\r\n });\r\n }\r\n \r\n /**\r\n * filter memos\r\n * @memberof memosByCategory\r\n * @param {object} data\r\n */\r\n function filterMemos(data){\r\n //normalize memos\r\n var distinctMemos = normalizeMemos(data);\r\n\r\n if (distinctMemos.length != data.length) {\r\n MemoFactory.getMemosFromStorage(function (allMemos) {\r\n var distinctMemosAll = normalizeMemos(allMemos);\r\n MemoImagesFactory.getMemoImagesFromStorage(function (allMemoImages) {\r\n var distinctMemoImagesAll = normalizeMemoImages(allMemoImages);\r\n recreateIndexedDB(distinctMemosAll, allMemoImages);\r\n });\r\n });\r\n }\r\n var memosByCategory = [];\r\n for (var i = 0; i < distinctMemos.length; i++) {\r\n var memo = distinctMemos[i];\r\n if (!memosByCategory.filter(function (e) { return ( e.CategoryId != undefined && e.CategoryId == memo.CategoryId) || (e.Category != undefined && memo.Category == e.Category) }).length > 0) {\r\n memosByCategory.push({ CategoryId: memo.CategoryId, Category: memo.Category, memoList: [memo] });\r\n }\r\n else if (memosByCategory.filter(function (e) { return ( e.CategoryId != undefined && e.CategoryId == memo.CategoryId) || (e.Category != undefined && memo.Category == e.Category) }).length > 0) {\r\n memosByCategory.filter(function (object) {\r\n\r\n if (( object.CategoryId != undefined && object.CategoryId == memo.CategoryId) || (object.Category != undefined && memo.Category == object.Category)) {\r\n return object;\r\n };\r\n })[0].memoList.push(memo);\r\n }\r\n }\r\n return memosByCategory;\r\n }\r\n function recreateIndexedDB(distinctMemosAll, distinctMemosImagesAll) {\r\n //delete indexdb\r\n var q = DataCleanerFactory.deleteIndexedDB();\r\n q.then(function () {\r\n MemoFactory.setMemosToStorage(distinctMemosAll);\r\n MemoImagesFactory.setMemoImagesToStorage(distinctMemosImagesAll);\r\n\r\n //save normalize data to indexedDB\r\n LogService.debug(\"Recreated IndexedDB\");\r\n });\r\n q.catch(function (ex) {\r\n console.log(ex);\r\n });\r\n\r\n }\r\n function normalizeMemos(data) {\r\n var distinctData = [];\r\n if (data && data.length > 1) {\r\n var sortData = data.dynamicSort(\"Id\");\r\n for (var i = 0; i < sortData.length - 1; i++) {\r\n if (sortData[i + 1].Id == sortData[i].Id) {\r\n //swap rows in list - check lastUpdated property, latest at the end\r\n if (sortData[i].LastUpdated && sortData[i + 1].LastUpdated) {\r\n var memoDateA = new Date(sortData[i].LastUpdated);\r\n var memoDateB = new Date(sortData[i + 1].LastUpdated);\r\n if (memoDateA.getTime() > memoDateB.getTime()) {\r\n var temp = sortData[i + 1];\r\n sortData[i + 1] = sortData[i];\r\n sortData[i] = temp;\r\n }\r\n }\r\n } else {\r\n distinctData.push(sortData[i]);\r\n }\r\n }\r\n distinctData.push(sortData[sortData.length - 1]);\r\n } else {\r\n distinctData = data;\r\n }\r\n\r\n return distinctData\r\n }\r\n function normalizeMemoImages(data) {\r\n var distinctData = [];\r\n if (data && data.length > 1) {\r\n var sortData = data.dynamicSort(\"imageId\");\r\n for (var i = 0; i < sortData.length - 1; i++) {\r\n if (!(sortData[i + 1].imageId == sortData[i].imageId)) {\r\n distinctData.push(sortData[i]);\r\n }\r\n }\r\n distinctData.push(sortData[sortData.length - 1]);\r\n } else {\r\n distinctData = data;\r\n }\r\n\r\n return distinctData\r\n }\r\n\r\n $scope.openMemo = openMemo;\r\n\r\n\r\n /**\r\n * Open modal to see information for the selected Memo\r\n * @memberof memosByCategory\r\n * @param {object} memo A memo object\r\n */\r\n function openMemo(memo) {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgMemo.html',\r\n controller: 'MemoModalCtrl',\r\n size: 'lg',\r\n keyboard: false,\r\n resolve: {\r\n memo: function () {\r\n return memo;\r\n }\r\n }\r\n });\r\n\r\n modalInstance.result.then(function () {\r\n if (memo.ReadDt == null) {\r\n memo.ReadDt = new Date();\r\n MemoFactory.saveOneMemoToStorage(memo);\r\n\r\n if($scope.type == \"ground\"){\r\n MemoFactory.markGroundDutiesUnread();\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n templateUrl: \"views/directives/memosByCategoryPanel.tpl.html\",\r\n scope: {\r\n type: '@',\r\n id: '=',\r\n day: '=' \r\n },\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();\r\n","(function () {\r\n\r\n a3_cabin_reports.directive('reportsPanel', reportsPanel);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name reportsPanel\r\n * @restrict E\r\n * @description\r\n * Implementation of reportsPanel\r\n * Initialize the panels with reports.\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function reportsPanel(SettingsMain, $location, $anchorScroll,enableWaterUpliftReporting, waterUpliftSupportingAcTypes,defaultCalendarDate) {\r\n function link($scope, element, attrs) {\r\n //Initialize CSS classes\r\n $scope.togglePanel = togglePanel;\r\n $scope.showSafetyReport = showSafetyReport();\r\n //$scope.showCampaignsFeedback = CampaignFactory.hasPendingFeedbacks($scope.flight.FlightId);\r\n $scope.goToCampaignsPanel = function () {\r\n $location.hash('campaigns');\r\n $anchorScroll();\r\n };\r\n\r\n if (attrs.assessmentOnly != \"true\") {\r\n $scope.showReports = true;\r\n $scope.getBottomClass = getBottomClass;\r\n $scope.getTextClass = getTextClass;\r\n $scope.getAssessmentTextClass = getAssessmentTextClass;\r\n $scope.getTopClass = getTopClass;\r\n $scope.hasIcon = hasIcon;\r\n $scope.isWaterUpliftRequired = isWaterUpliftRequired;\r\n } else {\r\n //Assessment only\r\n $scope.showReports = false;\r\n $scope.getBottomClass = \"\";\r\n if ($scope.crewRouteDuty && $scope.crewRouteDuty.AssessmentInfo) {\r\n $scope.getAssessmentTextClass = \"\";\r\n updateClassesForAssessment();\r\n $scope.assessmentStatus = $scope.crewRouteDuty.AssessmentInfo.IsExist || $scope.crewRouteDuty.AssessmentInfo.Status == \"Stored\" ? \"synched\" : $scope.crewRouteDuty.AssessmentInfo.Status;\r\n $scope.openAssessment = openAssessment;\r\n }\r\n }\r\n\r\n function showSafetyReport(){\r\n\r\n if(attrs.assessmentOnly != \"true\"){\r\n var today = new Date().toUTC();\r\n if(defaultCalendarDate){\r\n today = new Date(defaultCalendarDate).toUTC();\r\n }\r\n var flightDate = new Date($scope.flight.FlightDate);\r\n var trimmedToday = new Date(today);\r\n var trimmedFlightDate = new Date(flightDate);\r\n var diffDays = Date.DifferenceInDays(trimmedToday.trimTime(), trimmedFlightDate.trimTime());\r\n \r\n return diffDays <= 0;\r\n }\r\n else{\r\n return false;\r\n }\r\n }\r\n \r\n function isWaterUpliftRequired() {\r\n var today = new Date($scope.flight.FlightDate);\r\n return ((today.getDate() == 1 || today.getDate() == 15) && enableWaterUpliftReporting && waterUpliftSupportingAcTypes.includes($scope.flight.AcType))\r\n }\r\n\r\n /**\r\n * toggle Panel\r\n * @memberof reportsPanel\r\n * @param {number} panelId\r\n */\r\n function togglePanel(panelId) {\r\n $('#' + panelId).toggle();\r\n }\r\n\r\n /**\r\n * Return the text ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\r\n function getTextClass() {\r\n var classname = \"\";\r\n if ($scope.flight.LineStatus === 'na')\r\n classname = \"text-gray\";\r\n else if ($scope.flight.LineStatus === 'pending')\r\n classname = \"text-blue\";\r\n else if ($scope.flight.LineStatus === 'pendingoverdue')\r\n classname = \"text-blue\";\r\n else if (\r\n ($scope.flight.LineStatus === 'draft') ||\r\n ($scope.flight.LineStatus === 'draftotheruser')\r\n ) {\r\n classname = \"text-orange\";\r\n } else if (\r\n ($scope.flight.LineStatus === 'completed') ||\r\n ($scope.flight.LineStatus === 'completedotheruser')\r\n ) {\r\n classname = \"text-purple\";\r\n } else if (\r\n ($scope.flight.LineStatus === 'stored') ||\r\n ($scope.flight.LineStatus === 'storedotheruser') ||\r\n ($scope.flight.LineStatus === 'stored+otheruser') ||\r\n ($scope.flight.LineStatus === 'synched') ||\r\n ($scope.flight.LineStatus === 'synchedotheruser')\r\n ) {\r\n classname = \"text-green\";\r\n }\r\n return classname;\r\n }\r\n\r\n\r\n /**\r\n * Return the panel upper ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\r\n function getTopClass() {\r\n var classname = \"\";\r\n if ($scope.flight.LineStatus === 'na')\r\n classname = \"border-top-gray\";\r\n else if ($scope.flight.LineStatus === 'pending')\r\n classname = \"border-top-blue\";\r\n else if ($scope.flight.LineStatus === 'pendingoverdue')\r\n classname = \"border-top-blue\";\r\n else if (\r\n ($scope.flight.LineStatus === 'draft') ||\r\n ($scope.flight.LineStatus === 'draftotheruser')\r\n ) {\r\n classname = \"border-top-orange\";\r\n } else if (\r\n ($scope.flight.LineStatus === 'completed') ||\r\n ($scope.flight.LineStatus === 'completedotheruser')\r\n ) {\r\n classname = \"border-top-purple\";\r\n } else if (\r\n ($scope.flight.LineStatus === 'stored') ||\r\n ($scope.flight.LineStatus === 'storedotheruser') ||\r\n ($scope.flight.LineStatus === 'stored+otheruser') ||\r\n ($scope.flight.LineStatus === 'synched') ||\r\n ($scope.flight.LineStatus === 'synchedotheruser')\r\n ) {\r\n classname = \"border-top-green\";\r\n }\r\n return classname;\r\n }\r\n\r\n /**\r\n * Return the panel border ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\r\n function getBottomClass() {\r\n var classname = \"\";\r\n if ($scope.flight.LineStatus === 'na')\r\n classname = \"border-bottom-gray\";\r\n else if ($scope.flight.LineStatus === 'pending')\r\n classname = \"border-bottom-blue\";\r\n else if ($scope.flight.LineStatus === 'pendingoverdue')\r\n classname = \"border-bottom-blue\";\r\n else if (\r\n ($scope.flight.LineStatus === 'draft') ||\r\n ($scope.flight.LineStatus === 'draftotheruser')\r\n ) {\r\n classname = \"border-bottom-orange\";\r\n } else if (\r\n ($scope.flight.LineStatus === 'completed') ||\r\n ($scope.flight.LineStatus === 'completedotheruser')\r\n ) {\r\n classname = \"border-bottom-purple\";\r\n } else if (\r\n ($scope.flight.LineStatus === 'stored') ||\r\n ($scope.flight.LineStatus === 'storedotheruser') ||\r\n ($scope.flight.LineStatus === 'stored+otheruser') ||\r\n ($scope.flight.LineStatus === 'synched') ||\r\n ($scope.flight.LineStatus === 'synchedotheruser')\r\n ) {\r\n classname = \"border-bottom-green\";\r\n }\r\n return classname;\r\n }\r\n\r\n /**\r\n * If report from another user exists, show icon\r\n * @memberof FlightInfoCtrl\r\n * @returns {boolean} hasIcon\r\n */\r\n function hasIcon() {\r\n var hasIcon = false;\r\n if (\r\n ($scope.flight.LineStatus === 'draftotheruser') ||\r\n ($scope.flight.LineStatus === 'completedotheruser') ||\r\n ($scope.flight.LineStatus === 'storedotheruser') ||\r\n ($scope.flight.LineStatus === 'stored+otheruser') ||\r\n ($scope.flight.LineStatus === 'synchedotheruser')\r\n ) {\r\n hasIcon = true;\r\n }\r\n return hasIcon;\r\n }\r\n\r\n /**\r\n * Returns the assessment Text Class\r\n * @memberof FlightInfoCtrl\r\n * @return {string} classname\r\n */\r\n function getAssessmentTextClass() {\r\n var classname = \"\";\r\n if ($scope.flight.assessment) {\r\n if ($scope.flight.assessment.IsExist || $scope.flight.assessment.Status === 'Stored' || $scope.flight.assessment.Status === 'Outdated') {\r\n classname = \"text-green\";\r\n } else if ($scope.flight.assessment.Status === 'Pending')\r\n classname = \"text-blue\";\r\n else if ($scope.flight.assessment.Status === 'Draft') {\r\n classname = \"text-orange\";\r\n } else if ($scope.flight.assessment.Status === 'Completed') {\r\n classname = \"text-purple\";\r\n }\r\n }\r\n return classname;\r\n }\r\n\r\n\r\n /**\r\n * Return the panel border & text ccs class accoriding to assessment status \r\n * @memberof reportsPanel\r\n * @returns {string} cssClass\r\n */\r\n function updateClassesForAssessment() {\r\n //default values\r\n $scope.getBottomClass = \"\";\r\n $scope.getAssessmentTextClass = \"\";\r\n if($scope.crewRouteDuty && $scope.crewRouteDuty.AssessmentInfo){\r\n if ($scope.crewRouteDuty.AssessmentInfo.IsExist || $scope.crewRouteDuty.AssessmentInfo.Status == \"Stored\") {\r\n $scope.getBottomClass = \"border-bottom-green\";\r\n $scope.getAssessmentTextClass = \"text-green\";\r\n } else if ($scope.crewRouteDuty.AssessmentInfo.Status == \"Pending\") {\r\n $scope.getBottomClass = \"border-bottom-blue\";\r\n $scope.getAssessmentTextClass = \"text-blue\";\r\n } else if ($scope.crewRouteDuty.AssessmentInfo.Status == \"Draft\") {\r\n $scope.getBottomClass = \"border-bottom-orange\";\r\n $scope.getAssessmentTextClass = \"text-orange\";\r\n } else if ($scope.crewRouteDuty.AssessmentInfo.Status == \"Completed\") {\r\n $scope.getBottomClass = \"border-bottom-purple\";\r\n $scope.getAssessmentTextClass = \"text-purple\";\r\n }\r\n }\r\n }\r\n /**\r\n * Open current's Flight Cabin Crew Feedback Report\r\n * @memberof flightFooter \r\n */\r\n function openAssessment() {\r\n\r\n SettingsMain.setEditingPage(null);\r\n $location.path(\"assessment/\" + $scope.firstFlightId);\r\n }\r\n }\r\n\r\n\r\n\r\n return {\r\n restrict: 'E',\r\n templateUrl: \"views/directives/reportsPanel.tpl.html\",\r\n scope: true,\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function () {\r\n\r\n a3_cabin_reports.directive('securitySearch', securitySearch);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name securitySearch\r\n * @restrict E\r\n * @description\r\n * Implementation of securitySearch\r\n * Initialize the panel with previous flight info.\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function securitySearch(AircaftPositionsFactory, FlightFactory) {\r\n function link($scope) {\r\n var showSecurityMsg = false;\r\n var securitySearchRequired = null;\r\n var DepartureUK = null;\r\n var DepartureEU = null;\r\n var DepartureCDG = null;\r\n var PreviousEU = null;\r\n\r\n var aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId($scope.id);\r\n var flightInfo = FlightFactory.getFlightFromStorage($scope.id);\r\n\r\n if(flightInfo){\r\n DepartureUK = flightInfo.DepartureCountry == \"UNITED KINGDOM\";\r\n DepartureEU = flightInfo.DepartureEU;\r\n DepartureCDG = flightInfo.Departure == \"CDG\";\r\n\r\n // RULE 1: Current Departure Airport is UK\r\n // RULE 2: Current Departure Airport is Non EU\r\n // RULE 3: Current Departure Airport is CDG Airport\r\n if(DepartureUK || !DepartureEU || DepartureCDG){\r\n securitySearchRequired = true;\r\n }\r\n else{\r\n securitySearchRequired = false;\r\n }\r\n\r\n }\r\n \r\n if(aircaftPositions){\r\n // RULE 4: Previous Origin Airport is Non EU\r\n PreviousEU = aircaftPositions.PreviousEU; \r\n if(!PreviousEU){\r\n securitySearchRequired = true;\r\n }\r\n else{\r\n securitySearchRequired = false;\r\n }\r\n }\r\n \r\n if(securitySearchRequired != null){\r\n showSecurityMsg = true;\r\n }\r\n\r\n $scope.showSecurityMsg = showSecurityMsg;\r\n $scope.securitySearchRequired = securitySearchRequired;\r\n $scope.aircaftPositions = aircaftPositions;\r\n }\r\n return {\r\n restrict: 'E',\r\n templateUrl: \"views/directives/securitySearch.tpl.html\",\r\n scope: {\r\n id: '='\r\n },\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('showerrormessage', showerrormessage);\r\n\r\n /**\r\n * @ngdoc directive\r\n * @name showerrormessage\r\n * @restrict EA\r\n * @description\r\n * Implementation of show error message\r\n * @attr {String} message: the error message.\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */ \r\n function showerrormessage() {\r\n\r\n function link($scope, element, attrs) {\r\n $scope.errorMessage = attrs.message;\r\n $scope.hasMessage = attrs.message != null && attrs.message.length > 0;\r\n\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n template: '
{{errorMessage}}
',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})(); ","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('ssr',ssr);\r\n\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name ssr\r\n * @restrict EA\r\n * @description\r\n * Implementation of issues\r\n *\r\n * Initialize the special service template\r\n * @attr {String} format The name of the format to initialize the ssr.\r\n * @example\r\n * Usage:\r\n *
\r\n * @ngInject\r\n */ \r\nfunction ssr($sce,ssrCodes,waterUpliftSupportingAcTypes) {\r\n\r\n\t\r\n\t\treturn {\r\n\t\t\trestrict: 'EA',\r\n\t\t\tterminal: true,\r\n templateUrl: 'views/directives/ssr.tpl.html',\r\n\t\t\tscope: {\r\n paxInfo: '=',\r\n flight: '='\r\n },\r\n link: function ($scope, element, attrs) {\r\n $scope.format = attrs.format;\r\n $scope.VIP = detailedInfo('VIP');\r\n $scope.UPGD = detailedInfo('UPGD');\r\n $scope.FQTVGold = detailedInfo('FQTVGold');\r\n $scope.FQTVSilver = detailedInfo('FQTVSilver');\r\n $scope.UMNR = detailedInfo('UMNR');\r\n $scope.PRM = detailedInfo('WCBD,WCBW,WCHC,WCHR,WCHS,WCLB,WCMP,WCOB')\r\n $scope.DEAF = detailedInfo('DEAF')\r\n $scope.BLND = detailedInfo('BLND')\r\n $scope.DPNA = detailedInfo('DPNA')\r\n $scope.DEP = detailedInfo('DEPA,DEPU,ESCD')\r\n $scope.INAD = detailedInfo('INAD')\r\n $scope.MEDA = detailedInfo('AOXY,MEDA,MEQT,POXY')\r\n $scope.CBBG = detailedInfo('CBBG')\r\n $scope.OTH = detailedInfo('AVIH,BIKE,EMIG,ESAN,EXST,FAMS,GPST,HAJJ,PETC,SVAN,WEAP,XBGS,MAAS')\r\n $scope.UndeliveredChargeableSeats = detailedInfo('UndeliveredChargeableSeats')\r\n\r\n $scope.showFQTVGold = false;\r\n $scope.showFQTVSilver = false;\r\n $scope.showUMNR = false;\r\n $scope.showPRM = false;\r\n $scope.showDEAF = false;\r\n $scope.showBLND = false;\r\n $scope.showDPNA = false;\r\n $scope.showDEP = false;\r\n $scope.showINAD = false;\r\n $scope.showMEDA = false;\r\n $scope.showCBBG = false;\r\n $scope.showOTH = false;\r\n $scope.showIrregularites = false;\r\n $scope.showVIP = false;\r\n \r\n \r\n $scope.hasZones = hasZones;\r\n $scope.zoneC = getZone('C');\r\n $scope.zoneY = getZone('Y'); \r\n \r\n $scope.waterQuantity = getWaterQuantity();\r\n $scope.supportsWaterUpliftAcType = supportsWaterUpliftAcType(); \r\n \r\n $scope.UMNRDetails = umnrInfo('UMNR');\r\n\r\n function umnrInfo(umnr) {\r\n if($scope.paxInfo) {\r\n $scope.totalUMNR = [];\r\n $scope.paxInfo.Seatmap.forEach(function (row) {\r\n row.Columns.forEach(function (column) {\r\n if(column.SSR.IsUMNR)\r\n $scope.totalUMNR.push(column);\r\n });\r\n });\r\n } \r\n }\r\n\r\n function supportsWaterUpliftAcType(){\r\n return waterUpliftSupportingAcTypes.includes($scope.flight.AcType);\r\n }\r\n \r\n function getWaterQuantity(){\r\n var totalPax = $scope.flight.BookedC + $scope.flight.BookedY;\r\n var startDate = moment($scope.flight.ScheduledDeparture);\r\n var endDate = moment($scope.flight.ScheduledArrival);\r\n var duration = moment.duration(endDate.diff(startDate)).asHours();\r\n var waterQuantity = (0,18 * totalPax * duration)/200;\r\n var formattedwaterQuantity = waterQuantity.toString().substring(0,4);\r\n return formattedwaterQuantity;\r\n }\r\n \r\n function hasZones(){\r\n var retVal = false;\r\n if($scope.flight && $scope.flight.Zones && $scope.flight.Zones.length > 0)\r\n retVal = true;\r\n return retVal;\r\n }\r\n\r\n function getZone (classService) {\r\n var retVal = '';\r\n var zone;\r\n if($scope.flight && $scope.flight.Zones){\r\n // zone = $scope.flight.Zones.find(function (item) {\r\n // return item.Class == classService || item.Class == '';\r\n // });\r\n\r\n for (var i=0; i<$scope.flight.Zones.length; i++) {\r\n if($scope.flight.Zones[i].Class == classService || $scope.flight.Zones[i].Class == ''){\r\n zone = $scope.flight.Zones[i];\r\n break;\r\n }\r\n }\r\n }\r\n if(zone)\r\n retVal = zone.Title;\r\n return retVal;\r\n } \r\n\r\n\r\n\r\n function detailedInfo(properties){\r\n var propertiesArray = properties.split(',');\r\n var htmlPopover = ''\r\n if($scope.paxInfo && $scope.paxInfo.PassengerSummaryC && $scope.paxInfo.PassengerSummaryY){\r\n if(propertiesArray.length>1){\r\n htmlPopover = '
C
Y
Total
';\r\n\r\n angular.forEach(propertiesArray,function(property){\r\n \r\n var Total = $scope.paxInfo.PassengerSummaryC[('Total'+property)] + $scope.paxInfo.PassengerSummaryY[('Total'+property)];\r\n if(Total>0){\r\n var code = '';\r\n for (var i = 0; i < ssrCodes.length ; i++){\r\n if(ssrCodes[i].code == property){\r\n code = ssrCodes[i].description;\r\n }\r\n }\r\n htmlPopover = htmlPopover + '
' + property + \"\";\r\n htmlPopover = htmlPopover + '' + code + \"\";\r\n htmlPopover = htmlPopover + '
' + $scope.paxInfo.PassengerSummaryC[property] + \"
\";\r\n htmlPopover = htmlPopover + '
' + $scope.paxInfo.PassengerSummaryY[property] + \"
\";\r\n \r\n htmlPopover = htmlPopover + '
' \r\n + Total\r\n + \"
\";\r\n }\r\n })\r\n }else{\r\n angular.forEach(propertiesArray,function(property){\r\n var Total = $scope.paxInfo.PassengerSummaryC[('Total'+property)] + $scope.paxInfo.PassengerSummaryY[('Total'+property)];\r\n htmlPopover = '
C ' + $scope.paxInfo.PassengerSummaryC[property] + '';\r\n htmlPopover = htmlPopover + ' Y ' + $scope.paxInfo.PassengerSummaryY[property] + '';\r\n if(Total){\r\n htmlPopover = htmlPopover + ' Total ' + Total + '';\r\n }\r\n htmlPopover = htmlPopover + '
';\r\n })\r\n }\r\n }\r\n \r\n return $sce.trustAsHtml(htmlPopover);\r\n }\r\n }\r\n\t\t}\r\n\t}\r\n\r\n\r\n\r\n})();\r\n\t","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('updateConfirm',updateConfirm);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name updateConfirm\r\n * @restrict E\r\n * @description\r\n * Implementation of aircraft differences\r\n *\r\n * Display the confirm textto update service workers version\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */ \r\nfunction updateConfirm(SWUpdateService) {\r\n function link($scope, element, attributes){\r\n //if serviceWorker registered\r\n if ($scope.SWRegistration != null) {\r\n $scope.needUpdate = null;\r\n $scope.update = update;\r\n \r\n //get waiting service worker if exists\r\n $scope.needUpdate = $scope.SWRegistration.waiting;\r\n\r\n //if waiting service woker exists check how long its been waiting\r\n if ($scope.needUpdate != null){ \r\n SWUpdateService.checkVersionExpiration($scope.SWRegistration);\r\n }\r\n }\r\n\r\n function update() {\r\n SWUpdateService.update($scope.SWRegistration);\r\n }\r\n\r\n }\r\n return {\r\n\t\t\trestrict: 'E',\r\n\t\t\tterminal: true,\r\n\t\t\ttemplateUrl: 'views/directives/updateConfirm.tpl.html',\r\n\t\t\tscope: true,\r\n link: link\r\n\t\t}\r\n}\r\n})();","// array functions\r\nArray.prototype.dynamicSort = function(property,orderByAsc) {\r\n function dynamicSortComparator(property,orderByAsc) {\r\n var sortOrder = orderByAsc ? 1 : -1;\r\n\r\n return function (a,b) {\r\n var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;\r\n return result * sortOrder;\r\n }\r\n }\r\n \r\n var sortedArray = this;\r\n if(property!=null && property != undefined){\r\n orderByAsc = orderByAsc == null || orderByAsc == undefined ? true : orderByAsc; \r\n sortedArray = this.sort(dynamicSortComparator(property,orderByAsc))\r\n }\r\n\treturn sortedArray;\r\n};\r\n\r\nArray.prototype.unique = function() {\r\n var arr = [];\r\n for(var i = 0; i < this.length; i++) {\r\n if(!arr.contains(this[i])) {\r\n arr.push(this[i]);\r\n }\r\n }\r\n return arr; \r\n};\r\nArray.prototype.contains = function(v) {\r\n for(var i = 0; i < this.length; i++) {\r\n if(this[i] === v) return true;\r\n }\r\n return false;\r\n};\r\n\r\nArray.prototype.groupByKey = function(key) {\r\n return this.reduce(function(rv, x) {\r\n (rv[x[key]] = rv[x[key]] || []).push(x);\r\n return rv;\r\n }, {});\r\n};","// date functions\r\nDate.prototype.toUTC = function() {\r\n\treturn new Date(this.getTime() + this.getTimezoneOffset() * 60 * 1000);\r\n};\r\n\r\nDate.prototype.fromUTC = function() {\r\n\treturn new Date(this.getTime() - this.getTimezoneOffset() * 60 * 1000);\r\n};\r\n\r\nDate.prototype.trimTime = function() {\r\n\tthis.setHours(0, 0, 0, 0);\r\n\treturn this;\r\n};\r\n\r\nvar _DatetoJSON = Date.prototype.toJSON;\r\nDate.prototype.toJSON = function() {\r\n try {\r\n return _DatetoJSON.call(this);\r\n } catch(e) {\r\n if (e instanceof RangeError) {\r\n return null;\r\n }\r\n throw e;\r\n }\r\n};\r\n\r\nDate.DifferenceInMinutes = function(firstDate, secondDate) {\r\n var diffInMins = null;\r\n if(firstDate && secondDate){\r\n var _MS_TO_MINUTES = 1000 * 60;\r\n var date1 = new Date(firstDate);\r\n var date2 = new Date(secondDate);\r\n diffInMins = Math.floor((date2.getTime() - date1.getTime()) / _MS_TO_MINUTES);\r\n }\r\n return diffInMins;\r\n};\r\n\r\nDate.DifferenceInDays = function (firstDate, secondDate) {\r\n var diffInDays = null;\r\n if (firstDate && secondDate){\r\n var _MS_TO_DAYS = 1000 * 3600 * 24;\r\n diffInDays = Math.floor((secondDate.getTime() - firstDate.getTime()) / _MS_TO_DAYS);\r\n }\r\n return diffInDays;\r\n}\r\n\r\n\r\nDate.MinutesToString = function(minutes){\r\n var hours = Math.floor( minutes / 60); \r\n var mins = minutes % 60;\r\n return (hours > 0 ? hours + (hours == 1 ? \"hr \": \"hrs \") : \"\") + (mins > 0 ? mins + (mins == 1 ? \"min\": \"mins\") : \"\");\r\n}\r\n\r\n\r\nDate.prototype.AddDays = function(days) {\r\n var date = new Date(this.valueOf());\r\n date.setDate(date.getDate() + days);\r\n return date;\r\n}\r\n \r\nDate.MinutesToStringSimple = function(minutes){\r\n var hours = Math.floor(minutes / 60); \r\n var mins = minutes % 60;\r\n return (hours != 0 ? (hours + \":\") : (\"00\" + \":\" )) + (mins > 9 ? mins : \"0\" + mins);\r\n}\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('FlightCrewMemberFactory', FlightCrewMemberFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightCrewMemberFactory\r\n * @description \r\n * Add, Update, Delete and Get Flight Crew Members.\r\n * @ngInject\r\n */ \r\nfunction FlightCrewMemberFactory(GenericModalFactory) {\r\n\r\n /**\r\n * Initialize the FlightCrewMember\r\n * @memberof FlightCrewMemberFactory\r\n */\r\n\t\tfunction FlightCrewMember() {\r\n\t\t\tthis.aimsId = null;\r\n\t\t\tthis.id = null;\r\n\t\t\tthis.isDHC = null;\r\n\t\t\tthis.name = null;\r\n\t\t\tthis.position = null;\r\n\t\t\tthis.sex = null;\r\n\t\t\tthis.shortname = null;\r\n\t\t}\r\n\t\t\r\n\t \tvar service = {\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tdeleteFromList : deleteFromList\r\n\t\t}\r\n\r\n /**\r\n * Extend Object from the default FlightCrewMember Object\r\n * @memberof FlightCrewMemberFactory\r\n * @param {Object} obj a FlightCrewMember\r\n * @returns {Object} FlightCrewMember\r\n */\r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericModalFactory.fromObject(obj,FlightCrewMember)\r\n\t\t}\r\n\r\n /**\r\n * Delete object from given list and update it\r\n * @memberof FlightCrewMemberFactory\r\n * @param {object} obj a Flight Crew Member\r\n * @param {Array} objList an Array Of Flight Crew Member\r\n * @returns {Array} FlightCrewMembers\r\n *\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\treturn GenericModalFactory.deleteFromList(obj, objList)\r\n\t\t}\r\n\r\n /**\r\n * Extend an array of Objects from the default Flight Crew Member Object\r\n * @memberof FlightCrewMemberFactory\r\n * @param {Array} objList an Array Of Flight Crew Member\r\n * @returns {Array} FlightCrewMembers\r\n */\r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericModalFactory.fromObjectList(objList,FlightCrewMember)\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n })();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('flightServiceEvents', flightServiceEvents);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name flightServiceEvents\r\n * @restrict E\r\n * @description\r\n * Implementation of flightServiceEvents panel\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function flightServiceEvents(FlightServiceEventsFactory, $sce, $uibModal) {\r\n function link(scope, element, attributes) {\r\n //scope.save = save;\r\n scope.events = [];\r\n scope.eventTypes = [];\r\n scope.openEvent = openEvent;\r\n scope.isRefreshing = false;\r\n scope.refreshEvents = refreshEvents;\r\n \r\n //get from LS the events & the types\r\n getEventsNTypes(scope.flightId);\r\n \r\n function getEventsNTypes(flightId){\r\n scope.showPanel = null;\r\n scope.eventTypes = FlightServiceEventsFactory.getEventTypes();\r\n scope.events = FlightServiceEventsFactory.getEventsByFlightIdFromLS(flightId);\r\n //Merge eventTypes and events using common Code property\r\n scope.eventTypes.forEach(type => {\r\n var eventInType = scope.events.filter(x=>x.EventCode == type.Code);\r\n if(eventInType[0]){\r\n type.event = eventInType[0];\r\n }\r\n else{\r\n type.event =\r\n {\r\n FlightId: flightId,\r\n EventTypeId: type.Id,\r\n EventCode: type.Code,\r\n StartTime: null,\r\n EndTime: null,\r\n NotRequired: null,\r\n Remarks: null\r\n };\r\n }\r\n });\r\n }\r\n\r\n function refreshEvents(){\r\n scope.isRefreshing = true;\r\n if(scope.isOffline){\r\n scope.showPanel = \"offline\";\r\n scope.isRefreshing = false;\r\n }\r\n else{\r\n FlightServiceEventsFactory.getEvents(scope.flightId)\r\n .then(res => handleRefreshResponse(res));\r\n }\r\n\r\n }\r\n \r\n function handleRefreshResponse(results){\r\n if(results && results.data && results.data.success && results.data.data && results.data.data.length>0){\r\n FlightServiceEventsFactory.setEventsForFlightId(scope.flightId, results.data.data);\r\n getEventsNTypes(scope.flightId);\r\n }\r\n scope.isRefreshing = false;\r\n }\r\n\r\n /**\r\n * Open modal to see information for the selected Memo\r\n * @memberof memosByCategory\r\n * @param {object} eventType with event object\r\n */\r\n function openEvent(eventType) {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/FlightServiceEvents/dlgEventForm.html',\r\n controller: 'EventFormModalCtrl',\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n eventType: function () {\r\n return eventType;\r\n }\r\n }\r\n });\r\n \r\n modalInstance.result.then(function () {\r\n //dismiss event\r\n refreshEvents();\r\n }, function () {\r\n //close event\r\n refreshEvents();\r\n \r\n\t\t\t\t});\r\n\r\n\r\n \r\n }\r\n\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/FlightServiceEvents/flightServiceEvents.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('GroundDutyCtrl', GroundDutyCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name GroundDutyCtrl\r\n * @description \r\n * Shows the ground duty information\r\n * @ngInject\r\n */\r\n function GroundDutyCtrl(GroundDutyFactory, CourseFactory, TrainingSessionFactory, $scope, $location, $routeParams) {\r\n $scope.toggleCrewList = toggleCrewList\r\n $scope.toggleEditMode = toggleEditMode;\r\n $scope.selectTrainee = selectTrainee;\r\n $scope.refresh = refresh;\r\n $scope.refreshSuccess = true;\r\n $scope.isRefreshing = false;\r\n $scope.instructors = [];\r\n $scope.trainees = [];\r\n var groundDutyId = Number($routeParams.groundDutyId);\r\n var groundDuty = GroundDutyFactory.getGroundDutyFromStorage(groundDutyId);\r\n $scope.dutyCourses = GroundDutyFactory.getGroundDutyActiveCourses(groundDutyId);\r\n $scope.groundDutyId = groundDutyId;\r\n\r\n\r\n if (!groundDuty) {\r\n // go to dashboard if no groundDuty\r\n $location.path(\"/\");\r\n } else {\r\n //Toggle trainees\r\n groundDuty.Trainees.forEach(function (relatedTrainees) {\r\n relatedTrainees.isCollapsed = false;\r\n relatedTrainees.dynamicSize = 10;\r\n });\r\n\r\n //Collect all trainees in list\r\n var traineesFlat = [];\r\n groundDuty.Trainees.forEach(function (related) {\r\n related.CrewMembers.forEach(function (trainee) {\r\n traineesFlat.push(trainee);\r\n });\r\n });\r\n groundDuty.traineesFlat = traineesFlat;\r\n\r\n\r\n if (groundDuty.RelatedGroundDuties) {\r\n $scope.courses = GroundDutyFactory.getGroundDutyActiveCourses(groundDutyId);\r\n }\r\n\r\n updateCrewMemberScopes(groundDuty);\r\n\r\n $scope.groundDuty = groundDuty;\r\n $scope.groundDutyId = groundDutyId;\r\n }\r\n\r\n function toggleCrewList(relatedTrainees) {\r\n relatedTrainees.isCollapsed = !relatedTrainees.isCollapsed;\r\n\r\n if (relatedTrainees.isCollapsed) relatedTrainees.dynamicSize = relatedTrainees.CrewMembers.length;\r\n else relatedTrainees.dynamicSize = 10;\r\n }\r\n\r\n function toggleEditMode(elem, className) {\r\n $('body').find('div#' + elem + ' > div').not('.tip').hide(\"slow\");\r\n $('body').find('div#' + elem + ' div.' + className).not('.tip').show(\"slow\");\r\n }\r\n\r\n /**\r\n * Edit ground duty's attendance list\r\n * @param {object} trainee \r\n */\r\n function selectTrainee(trainee) {\r\n //Value will be saved in ground duty's crew members\r\n trainee.Absent = !trainee.Absent;\r\n GroundDutyFactory.updateGroundDuty($scope.groundDuty);\r\n }\r\n\r\n /**\r\n * Sync ground duty\r\n */\r\n function refresh() {\r\n var courseIds = $scope.dutyCourses.map(x => x.CourseId).filter(onlyUnique);\r\n\r\n var refreshGroundDuty = {\r\n DutyId: groundDutyId,\r\n CourseIds: courseIds\r\n };\r\n\r\n $scope.isRefreshing = true;\r\n\r\n //get latest info\r\n GroundDutyFactory.refresh(refreshGroundDuty, function (responseData) {\r\n\r\n $scope.isRefreshing = false;\r\n $scope.refreshSuccess = true;\r\n\r\n //update ground duty.\r\n var groundDuty = responseData.data.GroundDuty;\r\n if (groundDuty && groundDuty.Id != 0 && groundDuty.Code) {\r\n GroundDutyFactory.mergeGroundDutyInfo(groundDuty);\r\n }\r\n\r\n //Save training\r\n var trainingCourses = responseData.data.TrainingCourses;\r\n if (trainingCourses && trainingCourses.length) {\r\n trainingCourses.forEach(function (trainingCourse) {\r\n CourseFactory.upsertCourse(trainingCourse, function (course) {\r\n TrainingSessionFactory.applyTraineeInfoToSession(course, course.Id, $scope.groundDuty.DutyDateS, groundDutyId, function (session) {\r\n });\r\n });\r\n });\r\n }\r\n\r\n updateCrewMemberScopes(groundDuty);\r\n\r\n })\r\n .catch(function () {\r\n $scope.refreshSuccess = false;\r\n $scope.isRefreshing = false;\r\n });\r\n }\r\n\r\n function updateCrewMemberScopes(groundDuty) {\r\n if (groundDuty && groundDuty.RelatedGroundDuties && groundDuty.RelatedGroundDuties.length > 0) {\r\n var relatedDutyIns = groundDuty.RelatedGroundDuties.filter(x => x.IsInstructor == true);\r\n if (relatedDutyIns && relatedDutyIns.length > 0) {\r\n $scope.instructors = relatedDutyIns[0].CrewMembers;\r\n }\r\n var relatedDutyTr = groundDuty.RelatedGroundDuties.filter(x => x.IsInstructor == false);\r\n if (relatedDutyTr && relatedDutyTr.length > 0) {\r\n $scope.trainees = relatedDutyTr.flatMap(a => a.CrewMembers);\r\n }\r\n }\r\n }\r\n\r\n function onlyUnique(value, index, self) {\r\n return self.indexOf(value) === index;\r\n }\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n \r\n\r\na3_cabin_reports.factory('http401interceptor', http401interceptor);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name http401interceptor\r\n * @description \r\n * Redirect HTTP401 to login page, examine json format on success\r\n * @ngInject\r\n */\r\nfunction http401interceptor($q, $location, $log, LogService) {\r\n\t\treturn {\r\n\t\t\t'response': function(response) {\r\n // do something on success\r\n\t\t\t\t//expecting specific object as a response: success:true/false,errorMessage:string,data:any not null object\r\n\t\t\t\t//var contentType=response.headers(\"content-type\");\r\n\t\t\t\tvar header = \"\";\r\n\t\t\t\tif (typeof response != 'undefined' && response != null && response && typeof response.headers != 'undefined' && response.headers != null && response.headers && response.headers() && response.headers(\"content-type\"))\r\n\t\t\t\t\theader = response.headers(\"content-type\").substring(0, 16);\r\n\r\n\t\t\t\tif (header === \"application/json\") {\r\n\t\t\t\t\tvar errorMessage = \"\";\r\n\t\t\t\t\tvar isError = false;\r\n\t\t\t\t\tif (response == null || response.data == null || response.data.success == null || response.data.errorMessage == null || response.data.data === 'undefined') {\r\n\t\t\t\t\t\tisError = true;\r\n\t\t\t\t\t\terrorMessage = \"Server response not found\";\r\n\t\t\t\t\t} else if (response.data.success == false) {\r\n\t\t\t\t\t\tisError = true;\r\n\t\t\t\t\t\terrorMessage = response.data.errorMessage;\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (isError) $q.reject(response, errorMessage);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t//try to log error cases\r\n\t\t\t\t\tvar err = null;\r\n\t\t\t\t\tif (typeof response === 'undefined' || response == null)\r\n\t\t\t\t\t\terr = \"Response was empty\";\r\n\t\t\t\t\telse if (!response.headers)\r\n\t\t\t\t\t\terr = \"Response does not contain headers\";\r\n\t\t\t\t\telse if (!response.status)\r\n\t\t\t\t\t\terr = \"Response does not have a status\";\r\n\t\t\t\t\telse if (response.status >= 400)\r\n\t\t\t\t\t\terr = \"Response status was \" + response.status + \" instead of 200\";\r\n\r\n\t\t\t\t\tif (err != null)\r\n\t\t\t\t\t\tLogService.debug(err);\r\n\t\t\t\t}\r\n\r\n\t\t\t\treturn response || $q.when(response);\r\n\t\t\t},\r\n\t\t\t// optional method\r\n\t\t\t'responseError': function(rejection) {\r\n\t\t\t\tif (rejection.status === 401) {\r\n\t\t\t\t\t$log.error('Authorization failed. Need to login again');\r\n\t\t\t\t\tif ($location.path() != '/login') {\r\n\t\t\t\t\t\t$location.path('/login');\r\n\t\t\t\t\t\t//force refresh so that the browser will download any updates from the cache.manifest\r\n\t\t\t\t\t\t//without refresh, user may stick to an older version for ever\r\n\t\t\t\t\t\tsetTimeout(function() {\r\n\t\t\t\t\t\t\twindow.location.reload(true);\r\n\t\t\t\t\t\t}, 1000);\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn $q.reject(rejection);\r\n\t\t\t\t} else {\r\n\t\t\t\t\treturn $q.reject(rejection);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('MessageFactory', MessageFactory)\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name MessageFactory\r\n * @description \r\n * Add, Update, Delete and Get Messages.\r\n * @ngInject\r\n */\r\nfunction MessageFactory(GenericService) {\r\n \r\n /**\r\n * Initialize the Message\r\n * @memberof MessageFactory\r\n */\r\n\t\tfunction Message() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.Title = null;\r\n\t\t\tthis.AuthorName = null;\r\n\t\t\tthis.Body = null;\r\n\t\t\tthis.AcType = null;\r\n\t\t\tthis.AirportA = null;\r\n\t\t\tthis.AirportB = null;\r\n\t\t\tthis.Country = null;\r\n\t\t\tthis.FlightDirection = null;\r\n\t\t\tthis.FlightNo = null;\r\n\t\t\tthis.ValidFrom = null;\r\n\t\t\tthis.ValidTo = null;\r\n\t\t\tthis.PositionCP = true;\r\n\t\t\tthis.PositionFA = true;\r\n\t\t\tthis.PositionFO = true;\r\n\t\t\tthis.PositionSA = true;\r\n\t\t\tthis.QueryType = null;\r\n\t\t\tthis.ReadDt = null;\r\n\t\t\tthis.Registration = null;\r\n\t\t\tthis.FeedbackCause = null;\r\n\t\t}\r\n\t\t\t\t\r\n\t\tvar objType = 'messages';\r\n\t\tvar objCallback = Message; \r\n\t\t\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tgetMessagesFromStorage : getMessagesFromStorage,\r\n\t\t\tsetMessagesToStorage : setMessagesToStorage,\r\n\t\t\tclearMessagesFromStorage : clearMessagesFromStorage,\r\n\t\t\tgetCountOfUnreadMessages : getCountOfUnreadMessages,\r\n\t\t\tgetMessagesFromIds : getMessagesFromIds,\r\n\t\t\tgetUnreadMessages : getUnreadMessages,\r\n\t\t\tmarkReaden : markReaden,\r\n\t\t\tmarkReadAsSynched : markReadAsSynched,\r\n\t\t\tgetUnsynchedReadMessages : getUnsynchedReadMessages,\r\n\t\t\tstoreMessagesFromServer : storeMessagesFromServer\r\n\t\t};\r\n\r\n /**\r\n * Extend an array of Objects from the default message Object\r\n * @memberof MessageFactory\r\n * @param {Array} objList an Array Of messages\r\n * @returns {Array} messages\r\n */\r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericService.fromObjectList(objList,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get messages\r\n * @memberof MessageFactory\r\n * @returns {Array} messages \r\n */\r\n\t\tfunction getMessagesFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save messages to storage\r\n * @memberof MessageFactory\r\n * @param {Array} messages A list of messages\r\n */\r\n\t\tfunction setMessagesToStorage(messages) {\r\n\t\t\tGenericService.saveAll(messages,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Remove the messages of the local storage\r\n * @memberof MessageFactory\r\n */\r\n\t\tfunction clearMessagesFromStorage() {\r\n\t\t\tGenericService.removeAll(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get count of unread messages\r\n * @memberof MessageFactory\r\n * @returns {number} result \r\n */\r\n\t\tfunction getCountOfUnreadMessages() {\r\n\t\t\tvar messages = getMessagesFromStorage();\r\n\t\t\tif (!messages)\r\n\t\t\t\treturn 0;\r\n\r\n\t\t\tvar result = 0;\r\n\t\t\tvar arrayLength = messages.length;\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (!messages[i].ReadDt) {\r\n\t\t\t\t\tresult++;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Get messages from given ids\r\n * @memberof MessageFactory\r\n * @param {Ids} List of Ids\r\n * @returns {Array} selectedMessages \r\n */\r\n\t\tfunction getMessagesFromIds(Ids) {\r\n\t\t\tvar messages = getMessagesFromStorage();\r\n\t\t\tvar selectedMessages = [];\r\n\t\t\tif (Ids != undefined || Ids != null) {\r\n\t\t\t\tfor (var i = 0; i < Ids.length; i++) {\r\n\t\t\t\t\tfor (var j = 0; j < messages.length; j++) {\r\n\t\t\t\t\t\tif (Ids[i] == messages[j].Id) {\r\n\t\t\t\t\t\t\tselectedMessages.push(messages[j]);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn selectedMessages;\r\n\t\t}\r\n\r\n /**\r\n * Get unread messages\r\n * @memberof MessageFactory\r\n * @returns {Array} filteredMessages \r\n */\r\n\t\tfunction getUnreadMessages() {\r\n\t\t\tvar messages = getMessagesFromStorage();\r\n\t\t\tfilteredMessages = [];\r\n\r\n\t\t\tfor (var i = 0; i < messages.length; i++) {\r\n\t\t\t\tif (!messages[i].ReadDt == null) {\r\n\t\t\t\t\tfilteredMessages.push(messages[i])\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn filteredMessages;\r\n\t\t}\r\n\r\n /**\r\n * Mark the message as read and save it\r\n * @memberof MessageFactory\r\n * @param {string} messageId The message identifier\r\n */\r\n\t\tfunction markReaden(messageId) {\r\n\t\t\t// get the Message array from storage\r\n\t\t\tvar messages = getMessagesFromStorage();\r\n\t\t\tif (messages == null)\r\n\t\t\t\tmessages = [];\r\n\r\n\t\t\t// find the current Message from the array (if present)\r\n\t\t\tvar arrayLength = messages.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (messages[i].Id == messageId) {\r\n\t\t\t\t\tmessages[i].ReadDt = new Date();\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tsetMessagesToStorage(messages);\r\n\t\t}\r\n\r\n /**\r\n * Mark the messages as synched and save it\r\n * @memberof MessageFactory\r\n * @param {array} readMessages A list of synced messages\r\n */\r\n\t\tfunction markReadAsSynched(readMessages) {\r\n\t\t var messages = getMessagesFromStorage();\r\n\t\t if (readMessages && messages){\r\n\t\t\t\t var id;\r\n\t\t\t\t for (var i=0;i 0){\r\n\t\t\t\tfiltered = [];\r\n\t\t\t\tfor (var i=0;i= 0) {\r\n\t\t\t\t// remove the guid from the array\r\n\t\t\t\treportGuids.splice(validGuidIndex, 1);\r\n\r\n\t\t\t\t// save the new array\r\n\t\t\t\t setReportGuidsToStorage(toObjectList(reportGuids));\r\n\t\t\t}\r\n\r\n\t\t\treturn resultingGuid;\r\n\t\t}\r\n\r\n /**\r\n * Restore previously used guid into the pool of guids,Used when a report is being cancelled or deleted (and it has not been sent to the server)\r\n * @memberof ReportGuidFactory\r\n * @param {string} reportGuid\r\n */\r\n\t\tfunction restoreGuid(guid) {\r\n\t\t\t//reject incorrect values\r\n\t\t\tif (typeof guid == 'undefined' || guid == null || guid == '')\r\n\t\t\t\treturn false;\r\n\t\t\tvar reportGuids = getReportGuidsFromStorage();\r\n\t\t\tif (reportGuids == null)\r\n\t\t\t\treportGuids = [];\r\n\r\n\t\t\tvar arrayLength = reportGuids.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (reportGuids[i].Guid == guid) {\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t//add the guid into the pool of guids\r\n\t\t\tvar repGuid = fromObject(guid);\r\n\t\t\treportGuids.push(repGuid);\r\n\r\n\t\t\t// save the new array\r\n\t\t\tsetReportGuidsToStorage(toObjectList(reportGuids));\r\n\r\n\t\t\treturn true;\r\n\t\t}\r\n\r\n /**\r\n * Get the count of remaining reportGuid objects\r\n * @memberof reportGuid\r\n * @returns {number} reportGuidsLength\r\n */\r\n\t\tfunction getRemainingReportGuids() {\r\n\t\t\tvar reportGuids = getReportGuidsFromStorage();\r\n\t\t\tif (reportGuids == null)\r\n\t\t\t\treturn 0;\r\n\r\n\t\t\treturn reportGuids.length;\r\n\t\t}\r\n\r\n\treturn service;\r\n\t}\r\n\r\n})();","(function () {\r\n'use strict';\r\n\r\na3_cabin_reports.service(\"SWUpdateService\", SWUpdateService);\r\n\r\n/**\r\n* @memberof CabinReports\r\n* @ngdoc service\r\n* @name SWUpdateService\r\n* @description \r\n* manages the service-worker update\r\n* @ngInject\r\n*/\r\nfunction SWUpdateService(LogService) {\r\n /**\r\n * initialize service worker\r\n * @memberof SWUpdateService\r\n */\r\n function initialize() {\r\n // Delay registration until after the page has loaded\r\n window.addEventListener('load', function () {\r\n //kill switch. uncomment this and comment out everything else sw related\r\n // navigator.serviceWorker.getRegistrations().then(function (registrations) {\r\n // //returns installed service workers\r\n // if (registrations.length) {\r\n // for(var registration of registrations) {\r\n // registration.unregister();\r\n // }\r\n // }\r\n // });\r\n\r\n //register the service worker and work with the promise it returns\r\n navigator.serviceWorker.register('service-worker.js').then(function (reg) {\r\n // use a variable to make sure we refresh the page only once\r\n var refreshing;\r\n\r\n //fires when a new Service Worker takes control of the current page (refreshes the page)\r\n navigator.serviceWorker.addEventListener('controllerchange', function () {\r\n if (refreshing) return;\r\n refreshing = true;\r\n window.location.reload();\r\n });\r\n }).catch(function (e) {\r\n LogService.error(e, 'Tried to register the service worker');\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * poll the server for new service worker file (new app version)\r\n * @memberof SWUpdateService\r\n */ \r\n function checkUpdates(reg) {\r\n if (reg == null)\r\n return;\r\n \r\n //ask server for new service worker\r\n reg.update();\r\n }\r\n\r\n /**\r\n * If new service worker has been waiting too long, force update\r\n * @memberof SWUpdateService\r\n */\r\n function checkVersionExpiration(reg) {\r\n if (reg == null)\r\n return;\r\n reg.waiting.postMessage('checkVersionExpiration');\r\n }\r\n\r\n /**\r\n * Activate the new service worker that was waiting\r\n * @memberof SWUpdateService\r\n */\r\n function update(reg){\r\n reg.waiting.postMessage('skipWaiting');\r\n }\r\n\r\n return {\r\n initialize: initialize,\r\n checkUpdates: checkUpdates,\r\n checkVersionExpiration: checkVersionExpiration,\r\n update: update\r\n };\r\n}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('competences', competences);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name certificates\r\n * @restrict E\r\n * @description\r\n * Implementation of competences\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function competences($uibModal, $timeout) {\r\n function link(scope, element, attrs) {\r\n scope.manageCompetenceGrading = manageCompetenceGrading;\r\n scope.selectSubCompetence = selectSubCompetence;\r\n scope.openGradingModal = openGradingModal;\r\n\r\n scope.trainee.Competences.forEach(function(competence){\r\n competence.isCollapsed = competence.hasMandatory || competence.hasOptional;\r\n competence.showComments = competence.hasMandatory || competence.hasOptional || (competence.Comments && competence.Comments != \"\")\r\n });\r\n\r\n validateTraineeCompetences(scope.trainee);\r\n\r\n function validateTraineeCompetences(trainee){\r\n var missingGrading = trainee.Competences.some(c => c.Grading == null);\r\n var missingPerformanceIndicators = trainee.Competences.filter(c => c.hasMandatory).some(c => !c.SubCompetences.some(sub => sub.Selected));\r\n trainee.isCompetenceValid = !missingGrading && !missingPerformanceIndicators;\r\n } \r\n\r\n function manageCompetenceGrading(competence){\r\n var grading = competence.Grading ? Number(competence.Grading) : null;\r\n var hadMandatory = competence.hasMandatory;\r\n var hadOptional = competence.hasOptional;\r\n competence.hasMandatory = competence.MandatorySub.includes(grading);\r\n competence.hasOptional = competence.OptionalSub.includes(grading);\r\n competence.isCollapsed = competence.hasMandatory || competence.hasOptional;\r\n if(competence.isCollapsed) competence.showComments = true;\r\n \r\n //From Mandatory to None remove selected Sub Competences\r\n if( ((hadMandatory || hadOptional) && (!competence.hasMandatory && !competence.hasOptional))){\r\n competence.SubCompetences.forEach(function(sub){\r\n sub.Selected = false;\r\n });\r\n }\r\n\r\n validateTraineeCompetences(scope.trainee);\r\n\r\n switch (competence.Grading) {\r\n case 5:\r\n competence.GradingMessage = competence.GradeA;\r\n break;\r\n case 4:\r\n competence.GradingMessage = competence.GradeB;\r\n break;\r\n case 3:\r\n competence.GradingMessage = competence.GradeC;\r\n break;\r\n case 2:\r\n competence.GradingMessage = competence.GradeD;\r\n break;\r\n case 1:\r\n competence.GradingMessage = competence.GradeE;\r\n break;\r\n default:\r\n competence.GradingMessage = \"\";\r\n }\r\n\r\n scope.gradingSelection();\r\n }\r\n \r\n function selectSubCompetence(sub){\r\n sub.Selected = !sub.Selected;\r\n if(sub.Selected) scope.gradingSelection();\r\n validateTraineeCompetences(scope.trainee);\r\n }\r\n\r\n function openGradingModal(competence){\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgCompetenceGrading.html',\r\n controller: 'CompetenceModalCtrl',\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n competence: function () { return competence;},\r\n }\r\n });\r\n\r\n modalInstance.result.then(function (grading) {\r\n if(grading){\r\n manageCompetenceGrading(competence, grading);\r\n }\r\n });\r\n }\r\n }\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/Training/competences.tpl.html',\r\n scope: {trainee : \"=\", gradingSelection: \"&onGradingSelection\"},\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('FlightCourseCtrl', FlightCourseCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FlightCourseCtrl\r\n * @description \r\n *\r\n * @ngInject\r\n */\r\n function FlightCourseCtrl($route, $filter, $timeout, FlightSessionFactory, CrewRouteFactory, FlightFactory, GroundDutyFactory, CourseFactory, $scope, $location, $routeParams) {\r\n $scope.gotoCourse = gotoCourse;\r\n $scope.gotoCrewRoute = gotoCrewRoute;\r\n $scope.gotoFlight = gotoFlight;\r\n $scope.stickySelectedTrainee = stickySelectedTrainee;\r\n $scope.toggleView = toggleView;\r\n\r\n $scope.refreshCourse = refresh;\r\n $scope.courseTrainees = [];\r\n\r\n var courseId = Number($routeParams.courseId);\r\n var dutyNo = Number($routeParams.dutyNo);\r\n var dutyDay = Number($routeParams.dutyDay);\r\n $scope.viewFromFlight = Number($routeParams.flightId);\r\n\r\n var crewRouteDuty = CrewRouteFactory.getCrewRouteFromStorage(dutyNo, dutyDay);\r\n \r\n var date = $routeParams.date;\r\n crewRouteDuty.date = date;\r\n \r\n var crewRouteCourse = crewRouteDuty.Courses.find(x => x.CourseId == courseId && new moment(x.Date).isSame(date));\r\n\r\n $scope.isEdit = false;\r\n $scope.loading = false;\r\n $scope.refreshSuccess = true; //show refresh icon\r\n\r\n\r\n if (!crewRouteDuty) {\r\n // go to dashboard if no groundDuty\r\n $location.path(\"/\");\r\n } \r\n else \r\n {\r\n $scope.flights = FlightFactory.getFlightsByDutyNo(dutyNo, dutyDay);\r\n $scope.currentFlight = $scope.flights.filter(f => f.FlightId == Number($routeParams.flightId));\r\n\r\n var crewRouteTrainees = FlightSessionFactory.getCrewRouteFlightTrainees(dutyNo, dutyDay, crewRouteCourse.TrainingFlightIds)\r\n\r\n //Get Crew Route's course\r\n CourseFactory.getCourseFromStorage(courseId, function (savedCourse) {\r\n var dutyCourse = savedCourse;\r\n $scope.dutyCourse = dutyCourse;\r\n initCourse(false);\r\n });\r\n $scope.crewRouteDuty = crewRouteDuty;\r\n }\r\n\r\n\r\n function initCourse(afterRefresh) {\r\n var courseId = $scope.dutyCourse.Id;\r\n FlightSessionFactory.getSession(courseId, date, dutyNo, dutyDay, crewRouteCourse.TrainingFlightIds, afterRefresh, function (course) {\r\n if (course && !course.HasLimitedInfo) {\r\n $scope.availableCourse = true;\r\n \r\n $scope.selectedPhase = course.selectedPhase;\r\n $scope.trainees = course.CourseTrainees;\r\n course.SequenceWarning = false;\r\n }\r\n\r\n $scope.course = course;\r\n\r\n manageCourseStatus($scope.dutyCourse, course, afterRefresh);\r\n toggleView('History'); //default\r\n\r\n if ($scope.trainees) {\r\n stickySelectedTrainee();\r\n //Check for status change (new trainees found on a submitted session (reset) || failed certificate trainees want to retake the test)\r\n if (afterRefresh && $scope.isCourseComplete && $scope.trainees.length) {\r\n CrewRouteFactory.setCoursePending(dutyNo, dutyDay, courseId, date);\r\n $scope.isCourseComplete = false;\r\n $route.reload();\r\n }\r\n }\r\n\r\n $scope.reload = false;\r\n $timeout(function () {\r\n $scope.reload = true;\r\n }, 100);\r\n\r\n });\r\n }\r\n \r\n function gotoCourse(course) {\r\n $location.path('/course/' + course.Id + '/' + groundDuty.DutyDateS + \"/\" + groundDuty.Id);\r\n }\r\n\r\n function gotoCrewRoute(){\r\n $location.path('/crewRoute/'+ dutyNo + '/' + dutyDay);\r\n }\r\n\r\n function gotoFlight(){\r\n var flightId = Number($routeParams.flightId)\r\n $location.path('/flightinfo/' + flightId);\r\n }\r\n\r\n function refresh() {\r\n $scope.loading = true;\r\n\r\n if($scope.isOffline){\r\n $timeout(function () {\r\n $scope.loading = false;\r\n }, 100);\r\n $scope.refreshSuccess = false;\r\n $scope.availableCourseInfo = false;\r\n $scope.refreshErrorMsg = \"Online mode is required in order to get course. Please connect to the internet and try again.\";\r\n }\r\n else{\r\n CourseFactory.updateFlightCourseInfo(crewRouteCourse, date, dutyNo, dutyDay, function () {\r\n $scope.loading = false;\r\n $scope.refreshSuccess = true;\r\n $scope.availableCourseInfo = true;\r\n \r\n initCourse(true);\r\n $scope.reload = false;\r\n $timeout(function () {\r\n $scope.reload = true;\r\n }, 100);\r\n \r\n },\r\n function () {\r\n $scope.loading = false;\r\n $scope.refreshSuccess = false;\r\n $scope.availableCourseInfo = false;\r\n $scope.refreshErrorMsg = \"Something went wrong! Please Try again.\";\r\n },\r\n function (error) {\r\n console.log(error);\r\n $scope.loading = false;\r\n $scope.refreshSuccess = false;\r\n $scope.availableCourseInfo = false;\r\n\r\n $scope.refreshErrorMsg = \"Oops! Something went wrong!\";\r\n\r\n //null exception!\r\n // if (error.data.errorMessage) {\r\n // $scope.refreshErrorMsg = error.data.errorMessage;\r\n // }\r\n }\r\n )\r\n }\r\n }\r\n\r\n function manageCourseStatus(dutyCourse, course, afterRefresh) {\r\n // COMPLETED : has been submitted\r\n var isCourseComplete = crewRouteCourse.Status == \"Completed\";\r\n\r\n // NEEDS SUBMIT : 1 hour has passed since the end of the course\r\n var now = moment.utc();\r\n if (!dutyCourse.IsCompleted) {\r\n var needsSubmit = false;\r\n var fetched = moment.utc(crewRouteDuty.DutyEnd);\r\n var duration = moment.duration(now.diff(fetched)).asHours();\r\n if (duration > 1) {\r\n needsSubmit = true;\r\n }\r\n }\r\n \r\n // LIMITED : no info available\r\n var isCourseLimited = !course || course.HasLimitedInfo || (course.HasLimitedSession && !afterRefresh);\r\n\r\n // OUTDATED : NeedsRefresh || 18 hours since last refresh\r\n var isCourseOutdated = false;\r\n if (course && course.FetchedTime) {\r\n var now = moment.utc();\r\n var fetched = moment.utc(course.FetchedTime);\r\n var duration = moment.duration(now.diff(fetched)).asHours();\r\n\r\n if (duration > 18 || course.NeedsRefresh) {\r\n isCourseOutdated = true;\r\n }\r\n }\r\n\r\n var hasAdditionalTrainingRequest = false;\r\n if (course.SubmittedSessions && course.SubmittedSessions.length > 0) {\r\n if (course.SubmittedSessions.map(x => x.TraineesSessions.filter(y => y.UnderAdditionalTraining == true).length > 0)){\r\n hasAdditionalTrainingRequest = true;\r\n course.hasAdditionalTrainingRequest = true;\r\n };\r\n }\r\n\r\n var isUnderAdditionalTraining = false;\r\n if (course.SubmittedSessions && course.SubmittedSessions.length > 0) {\r\n if (course.SubmittedSessions.map(x => x.TraineesSessions.find(y => y.UnderAdditionalTraining == true))){\r\n isUnderAdditionalTraining = true;\r\n course.isUnderAdditionalTraining = true;\r\n };\r\n }\r\n\r\n $scope.headerMsg = \"Refresh Course\";\r\n if(isCourseLimited) $scope.headerMsg = \"Fetch Course\";\r\n\r\n $scope.hasPendingTraining = !isCourseComplete;\r\n $scope.hasUnsetTraining = needsSubmit;\r\n $scope.isCourseLimited = isCourseLimited;\r\n $scope.isCourseComplete = isCourseComplete;\r\n $scope.isCourseOutdated = isCourseOutdated;\r\n $scope.hasAdditionalTrainingRequest = hasAdditionalTrainingRequest;\r\n $scope.hasNotifications = isCourseLimited || isCourseOutdated || isCourseComplete;\r\n }\r\n\r\n function stickySelectedTrainee(){\r\n if($scope.trainees && $scope.trainees.filter(x => !x.Session.Absent).length){\r\n if($scope.trainees.filter(x => !x.Session.Absent).find(x => x.Session.selected)){\r\n $scope.selectedTrainee = $scope.trainees.filter(x => !x.Session.Absent).find(x => x.Session.selected);\r\n }\r\n else{\r\n $scope.selectedTrainee = $scope.trainees.filter(x => !x.Session.Absent)[0];\r\n }\r\n }\r\n else{\r\n $scope.selectedTrainee = null;\r\n }\r\n if($scope.selectedTrainee) $scope.selectedTraineeBadge = {CrewId:$scope.selectedTrainee.CrewId};\r\n }\r\n\r\n function toggleView(mode){\r\n $scope.viewMode = mode;\r\n }\r\n }\r\n})();\r\n","(function () {\r\n\r\n a3_cabin_reports.directive('media', media);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name ground Media\r\n * @restrict E\r\n * @description\r\n * Initialize panel with media of training selection, aircraft types & synthetic devices\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n\r\n function media($location, CourseFactory) {\r\n function link($scope, attrs) {\r\n\r\n $scope.addAircraftRow = addAircraftRow;\r\n $scope.removeAircraftRow = removeAircraftRow;\r\n\r\n $scope.showDowntimeDuration = showDowntimeDuration;\r\n $scope.clearDowntimeDuration = clearDowntimeDuration;\r\n \r\n $scope.isObjectEmpty = isObjectEmpty;\r\n \r\n $scope.downtimeDuration = {\r\n radioValue: 'false',\r\n show: false,\r\n minutes: null\r\n }\r\n $scope.sessionDuration = $scope.groundDuty ? (new Date($scope.groundDuty.DutyEnd) - new Date($scope.groundDuty.DutyBegin)) / (1000*60) : undefined;\r\n $scope.downtimeDurationValueChanged = downtimeDurationValueChanged;\r\n \r\n initializeMedia();\r\n\r\n $scope.filterSyntheticDevices = filterSyntheticDevices;\r\n \r\n function isObjectEmpty(obj){\r\n return Object.keys(obj).length === 0;\r\n }\r\n\r\n function initializeMedia() {\r\n if ($scope.course) {\r\n if (!$scope.course.Media) {\r\n // Create Media object\r\n $scope.course.Media = {\r\n inputAircrafts: [],\r\n selectedAircraft: {\r\n selection: undefined\r\n },\r\n selectedDevice: {\r\n selection: undefined\r\n },\r\n radioModel: \"\",\r\n };\r\n }\r\n\r\n if ($scope.course.Media.radioModel == \"\" || mediaRemoved()) {\r\n //Auto select media on init or if selection was removed in admin settings\r\n if ($scope.selectedPhase.InSimulator) $scope.course.Media.radioModel = \"Simulator\";\r\n if ($scope.selectedPhase.InAircraft) $scope.course.Media.radioModel = \"Aircraft\";\r\n if ($scope.selectedPhase.InClassroom) $scope.course.Media.radioModel = \"Classroom\";\r\n }\r\n\r\n if ($scope.selectedPhase.InSimulator) {\r\n // Check if training centers exist\r\n if ($scope.course.TrainingCenters && $scope.course.TrainingCenters.length > 0) {\r\n var defaultCenter = $scope.course.TrainingCenters.find(x => x.IsDefault);\r\n\r\n if (defaultCenter) {\r\n $scope.course.selectedTrainingCenter = defaultCenter.Id;\r\n filterSyntheticDevices(defaultCenter.Id);\r\n } else {\r\n // If no default center, select \"No Center\"\r\n $scope.course.selectedTrainingCenter = 'No Center';\r\n // No need to filter devices based on training center, show all devices\r\n filterSyntheticDevices('No Center');\r\n }\r\n }\r\n\r\n // Auto-select the first device if not already selected and devices exist\r\n if ($scope.course.SyntheticDevices && !isObjectEmpty($scope.course.SyntheticDevices)) {\r\n if (!$scope.course.Media.selectedDevice) {\r\n $scope.course.Media.selectedDevice = {};\r\n }\r\n\r\n if (!$scope.course.Media.selectedDevice.selection) {\r\n // Select the first available device\r\n $scope.course.Media.selectedDevice.selection = Object.keys($scope.course.SyntheticDevices)[0];\r\n }\r\n } else {\r\n // No devices available, clear the selection\r\n $scope.course.Media.selectedDevice.selection = undefined;\r\n }\r\n }\r\n\r\n // Create downtime duration object\r\n $scope.downtimeDuration = {\r\n radioValue: 'false',\r\n show: false,\r\n minutes: null\r\n }\r\n }\r\n }\r\n\r\n function filterSyntheticDevices(trainingCenterId) {\r\n if (!$scope.course.AllSyntheticDevices) {\r\n return;\r\n }\r\n\r\n if (trainingCenterId && trainingCenterId !== 'No Center') {\r\n $scope.course.SyntheticDevices = $scope.course.AllSyntheticDevices.filter(function (device) {\r\n return device.TrainingCenterId == trainingCenterId;\r\n });\r\n\r\n if ($scope.course.SyntheticDevices && $scope.course.SyntheticDevices.length > 0) {\r\n var defaultDevice = $scope.course.SyntheticDevices.find(function (device) {\r\n return device.IsDefault;\r\n });\r\n if (defaultDevice) {\r\n $scope.course.Media.selectedDevice.selection = defaultDevice.Id;\r\n } else {\r\n $scope.course.Media.selectedDevice.selection = null;\r\n }\r\n } else {\r\n $scope.course.Media.selectedDevice.selection = $scope.course.AllSyntheticDevices;\r\n }\r\n\r\n } else {\r\n $scope.course.SyntheticDevices = $scope.course.AllSyntheticDevices;\r\n }\r\n }\r\n \r\n function mediaRemoved(){\r\n return ($scope.course.Media.radioModel == \"Simulator\" && !$scope.selectedPhase.InSimulator) ||\r\n ($scope.course.Media.radioModel == \"Aircraft\" && !$scope.selectedPhase.InAircraft) ||\r\n ($scope.course.Media.radioModel == \"Classroom\" && !$scope.selectedPhase.InClassroom);\r\n }\r\n\r\n function addAircraftRow(){\r\n var aircraftTypes = $scope.course.AircraftTypes;\r\n if($scope.course.Media.selectedAircraft.selection != undefined && aircraftTypes && aircraftTypes.includes($scope.course.Media.selectedAircraft.selection) && (!$scope.course.Media.inputAircrafts || !$scope.course.Media.inputAircrafts.includes($scope.course.Media.selectedAircraft.selection))){\r\n //Add to selected\r\n if(!$scope.course.Media.inputAircrafts){\r\n $scope.course.Media.inputAircrafts = [];\r\n }\r\n $scope.course.Media.inputAircrafts.push($scope.course.Media.selectedAircraft.selection);\r\n \r\n //Remove from options\r\n $scope.course.AircraftTypes = aircraftTypes.filter(function(aircraft){\r\n return aircraft != $scope.course.Media.selectedAircraft.selection;\r\n });\r\n \r\n //Clear \r\n $scope.course.Media.selectedAircraft.selection = undefined;\r\n\r\n }\r\n }\r\n \r\n function removeAircraftRow(aircraft){\r\n //Remove from selected\r\n var acIndex = $scope.course.Media.inputAircrafts.indexOf(aircraft);\r\n $scope.course.Media.inputAircrafts.splice(acIndex, 1);\r\n \r\n //Add back to options\r\n $scope.course.AircraftTypes.push(aircraft);\r\n }\r\n\r\n function showDowntimeDuration(showDowntime) {\r\n if(showDowntime == true) {\r\n $scope.downtimeDuration.show = true;\r\n } else{\r\n $scope.downtimeDuration.show = false;\r\n }\r\n }\r\n\r\n function clearDowntimeDuration() {\r\n $scope.downtimeDuration.minutes = null;\r\n };\r\n\r\n function downtimeDurationValueChanged(){ \r\n if ($scope.downtimeDuration.minutes > $scope.sessionDuration) {\r\n $scope.downtimeDuration.minutes = $scope.sessionDuration;\r\n } \r\n return $scope.downtimeDuration.minutes;\r\n \r\n }\r\n\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n templateUrl: \"views/Training/media.tpl.html\",\r\n $scope : false,\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function() {\r\n\r\n a3_cabin_reports.directive('trainingMenu', trainingMenu);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name ground Course List\r\n * @restrict E\r\n * @description\r\n * Initialize navigation menu panel with with status indicators\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n\r\n function trainingMenu(CourseFactory, GroundDutyFactory, FlightFactory, CrewRouteFactory, $location, TrainingSessionFactory, FlightSessionFactory, $filter, $routeParams) {\r\n function link($scope, attrs) {\r\n $scope.gotoCourse = gotoCourse;\r\n $scope.hasPendingTraining = false;\r\n $scope.hasUnsetTraining = false;\r\n\r\n var groundSessions = [];\r\n var flightSessions = [];\r\n TrainingSessionFactory.getAll(function(savedGroundSessions) {\r\n FlightSessionFactory.getAll(function(savedFlightSessions) {\r\n groundSessions = savedGroundSessions;\r\n flightSessions = savedFlightSessions;\r\n\r\n $scope.courses = [];\r\n var duty = null;\r\n var dutyCourses = [];\r\n\r\n if ($scope.type == 'ground') {\r\n duty = GroundDutyFactory.getGroundDutyFromStorage($scope.id);\r\n $scope.duty = duty;\r\n\r\n if (duty && duty.RelatedGroundDuties) {\r\n dutyCourses = GroundDutyFactory.getGroundDutyActiveCourses($scope.id);\r\n if (dutyCourses) {\r\n CourseFactory.getCoursesFromStorageByIds(dutyCourses.map(function(course) { return course.CourseId }), function(savedCourses) {\r\n manageGroundCourseStatuses(duty, dutyCourses, savedCourses);\r\n\r\n //Overall panel color\r\n if(savedCourses.some(x => x.Status == \"Draft\")){\r\n $scope.PanelClass=\"border-bottom-orange\";\r\n }\r\n else if(savedCourses.some(x => x.Status == \"Pending\" || x.Status == \"Outdated\")){\r\n $scope.PanelClass=\"border-bottom-blue\";\r\n }\r\n else{\r\n $scope.PanelClass=\"border-bottom-green\";\r\n }\r\n\r\n $scope.courses = savedCourses;\r\n });\r\n }\r\n }\r\n }\r\n else if($scope.type == 'crewroute' || $scope.type == 'flight'){\r\n if($scope.type == 'crewroute'){\r\n duty = CrewRouteFactory.getCrewRouteFromStorage($scope.dutyNo, $scope.dutyDay);\r\n }\r\n else{\r\n duty = FlightFactory.getFlightFromTotalFlights($scope.id);\r\n }\r\n if (duty && duty.Courses) {\r\n dutyCourses = duty.Courses;\r\n CourseFactory.getCoursesFromStorageByIds(dutyCourses.map(function(course) { return course.CourseId }), function(savedCourses) {\r\n dutyCourses.forEach(function(dutyCourse){\r\n var savedCourse = savedCourses.find(x => x.Id == dutyCourse.CourseId);\r\n if(savedCourse){\r\n var course = {\r\n Id: savedCourse.Id,\r\n Title : savedCourse.Title,\r\n Day: new moment(dutyCourse.Date)\r\n };\r\n \r\n manageFlightCourseStatus(course, dutyCourse);\r\n $scope.courses.push(course);\r\n }\r\n \r\n });\r\n\r\n $scope.courses.forEach(function(course){\r\n course.FullDate = course.Day.format(\"YYYY-MM-DD\");\r\n course.Day = course.Day.format(\"DD/MM\");\r\n \r\n if($scope.courses.filter(x => x.Id == course.Id).length>1){\r\n course.IsMultiday = true;\r\n }\r\n \r\n });\r\n\r\n //Overall panel color\r\n if($scope.courses.some(x => x.Status == \"Draft\")){\r\n $scope.PanelClass=\"border-bottom-orange\";\r\n }\r\n else if($scope.courses.some(x => x.Status == \"Pending\" || x.Status == \"Outdated\")){\r\n $scope.PanelClass=\"border-bottom-blue\";\r\n }\r\n else{\r\n $scope.PanelClass=\"border-bottom-green\";\r\n }\r\n });\r\n }\r\n }\r\n \r\n });\r\n });\r\n\r\n function manageFlightCourseStatus(course, crewRouteCourse){\r\n var now=moment.utc();\r\n var flights = FlightFactory.getFlightsFromStorage().filter(x => crewRouteCourse.TrainingFlightIds.includes(x.FlightId));\r\n flights = $filter('orderBy')(flights, 'ScheduledArrival');\r\n var dutyEnd = flights[flights.length-1].ScheduledArrival;\r\n\r\n var dutyDate = new moment(crewRouteCourse.Date).format(\"YYYY-MM-DD\");\r\n\r\n var status=\"\";\r\n if(crewRouteCourse.Status == \"Pending\"){\r\n\r\n //Pending\r\n course.Status = \"Pending\";\r\n course.StatusClass = \"text-blue\";\r\n course.StatusDesc = \"pending\";\r\n \r\n //Outdated\r\n dutyEnd = moment.utc(dutyEnd);\r\n var duration = moment.duration(now.diff(dutyEnd)).asHours();\r\n if(duration>1){\r\n course.Status = \"Outdated\";\r\n }\r\n\r\n //Draft\r\n\t\t\t\t\tif(flightSessions && flightSessions.length > 0){\r\n\t\t\t\t\t\tvar existingSession = flightSessions.find(s => s != null && s.courseId == crewRouteCourse.CourseId && s.day == dutyDate && s.dutyDay == $scope.dutyDay && s.dutyNo == $scope.dutyNo);\r\n\t\t\t\t\t\tif(existingSession && !existingSession.HasLimitedInfo && existingSession.trainees && existingSession.trainees.length){\r\n\t\t\t\t\t\t\t//a training session with trainees exists\r\n course.Status = \"Draft\"\r\n course.StatusClass = \"text-orange\";\r\n course.StatusDesc = \"draft\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n }else if(crewRouteCourse.Status == \"Completed\"){\r\n //Completed\r\n course.Status = \"Completed\";\r\n course.StatusClass = \"text-green\";\r\n course.StatusDesc = \"synced\";\r\n }\r\n\r\n return status;\r\n }\r\n\r\n function manageGroundCourseStatuses(duty, dutyCourses, courses) {\r\n var now = moment.utc();\r\n\r\n courses.forEach(function(course) {\r\n var dutyCourse = dutyCourses.find(x => x.CourseId == course.Id);\r\n course.Status = dutyCourse.Status;\r\n\r\n /*Statuses\r\n \tCompleted : session has been sent\r\n \tOutdated :\tsession submission is overdue\r\n \tDraft\t : session completion has started but not submitted\r\n \tPending : session submission not yet due\r\n */\r\n\r\n if (course.Status == \"Pending\") {\r\n course.StatusClass = \"text-blue\";\r\n course.StatusDesc = \"pending\";\r\n\r\n //Outdated\r\n var dutyEnd = moment.utc(duty.DutyEnd);\r\n var duration = moment.duration(now.diff(dutyEnd)).asHours();\r\n if (duration > 1) {\r\n course.Status = \"Outdated\"\r\n }\r\n\r\n //Draft\r\n if (groundSessions && groundSessions.length) {\r\n var existingSession = groundSessions.find(s => s.courseId == course.Id && s.day == duty.DutyDateS && s.dutyId == duty.Id);\r\n if (existingSession && !existingSession.HasLimitedInfo && existingSession.trainees && existingSession.trainees.length) {\r\n //a training session with trainees exists\r\n course.Status = \"Draft\"\r\n course.StatusClass = \"text-orange\";\r\n course.StatusDesc = \"draft\";\r\n }\r\n }\r\n \r\n } else if (course.Status == \"Completed\") {\r\n //Completed\r\n course.Status = \"Completed\";\r\n course.StatusClass = \"text-green\";\r\n course.StatusDesc = \"synced\";\r\n }\r\n });\r\n\r\n \r\n }\r\n\r\n /**\r\n * Redirect to Course Session\r\n */\r\n function gotoCourse(course) {\r\n if($scope.type==\"ground\"){\r\n $location.path('/groundcourse/' + course.Id + '/' + $scope.duty.Id + \"/\" + $scope.duty.DutyDateS);\r\n }\r\n else if($scope.type==\"crewroute\"){\r\n $location.path('/flightcourse/' + course.Id + '/' + $scope.dutyNo + '/' + $scope.dutyDay + '/' + course.FullDate);\r\n }\r\n else if($scope.type==\"flight\"){\r\n $location.path('/flightcourse/' + course.Id + '/' + $scope.dutyNo + '/' + $scope.dutyDay + '/' + course.FullDate + '/' + Number($routeParams.flightId));\r\n }\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n templateUrl: \"views/Training/training-menu.tpl.html\",\r\n scope: {\r\n type: '@',\r\n id: '=',\r\n dutyNo: '=',\r\n dutyDay: '='\r\n },\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","// generic string functions\r\nString.prototype.endsWith = function(suffix) {\r\n\treturn this.indexOf(suffix, this.length - suffix.length) !== -1;\r\n};\r\n\r\nif (typeof String.prototype.startsWith != 'function') {\r\n\t// see below for better implementation!\r\n\tString.prototype.startsWith = function(str) {\r\n\t\treturn this.indexOf(str) == 0;\r\n\t};\r\n}\r\n\r\nString.prototype.reverse = function() {\r\n\treturn this.split(\"\").reverse().join(\"\");\r\n}\r\n\r\nString.prototype.getHash = function() {\r\n\tvar shaObj = new jsSHA(\"SHA-512\", \"TEXT\");\r\n\tshaObj.update(this);\r\n\tvar hash = shaObj.getHash(\"HEX\");\r\n\treturn hash;\r\n};\r\n\r\nString.prototype.elipsis = function(charNo) {\r\n\treturn this.length > charNo ? this.substring(0,charNo) + \"...\" : this; \r\n};\r\n ","(function () {\r\n 'use strict';\r\n a3_cabin_reports.directive('faceMasks', faceMasks);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name faceMasks\r\n * @restrict E\r\n * @description\r\n * Implementation of Face Masks \r\n *\r\n * Display the Face Masks Record Panel\r\n * @attr {String} flight-id\r\n * @example\r\n * Usage:\r\n * \r\n * \r\n * @ngInject\r\n */\r\n function faceMasks(FlightFactory, FaceMasksFactory, $sce, $timeout) {\r\n /**\r\n * Initialize faceMasks\r\n * @memberof faceMasks\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\r\n function link(scope, element, attributes) {\r\n scope.togglePanel = togglePanel;\r\n scope.submit = submit;\r\n scope.numberDown = numberDown;\r\n scope.numberUp = numberUp;\r\n scope.validInput = validInput;\r\n scope.validateForm = validateForm;\r\n scope.requiredFields = false;\r\n scope.invalidForm = false;\r\n scope.LastUpdated = null;\r\n\r\n initializePanel();\r\n\r\n /**\r\n * Initialize Form Values\r\n * @memberof faceMasks\r\n */\r\n function initializePanel(){\r\n var flight = FlightFactory.getFlightFromStorage(scope.flightId);\r\n \r\n \r\n var DryStoreFound = 0;\r\n var DryStoreLeft = 0;\r\n var UniversalFound = 0;\r\n var UniversalLeft = 0;\r\n\r\n //Check if there is existing data\r\n if(flight.FaceMasks){\r\n DryStoreFound = flight.FaceMasks.DryStoreFound;\r\n DryStoreLeft = flight.FaceMasks.DryStoreLeft;\r\n UniversalFound = flight.FaceMasks.UniversalFound;\r\n UniversalLeft = flight.FaceMasks.UniversalLeft;\r\n scope.LastUpdated = flight.FaceMasks.LastUpdated;\r\n }\r\n\r\n var masksForm = {\r\n Types: [{\r\n Type : \"A\",\r\n Title: \"FFP2 Masks\",\r\n Fields : [\r\n {\r\n Title: \"Found\",\r\n Value: DryStoreFound\r\n },\r\n {\r\n Title: \"Left\",\r\n Value: DryStoreLeft\r\n }\r\n ]\r\n },\r\n {\r\n Type : \"B\",\r\n Title: \"Surgical Face masks\", \r\n Fields : [\r\n {\r\n Title: \"Found\",\r\n Value: UniversalFound\r\n },\r\n {\r\n Title: \"Left\",\r\n Value: UniversalLeft\r\n }\r\n ]\r\n }\r\n ],\r\n FlightId: scope.flightId\r\n };\r\n \r\n scope.submitMessage = '';\r\n scope.masksForm = masksForm;\r\n scope.showPanel = \"masks\";\r\n validateForm();\r\n }\r\n \r\n /**\r\n * Check if all required fields exist and have a valid value\r\n * @memberof faceMasks\r\n */\r\n function validateForm(){\r\n scope.requiredFields = scope.masksForm.Types.some(t => t.Fields.some(f => f.Value === null))\r\n scope.invalidForm = scope.masksForm.Types.some(t => t.Fields.some(f => f.Value === undefined))\r\n\r\n //Hide other alerts when form is invalid\r\n if(scope.requiredFields || scope.invalidForm){\r\n scope.showPanel = \"masks\";\r\n }\r\n }\r\n\r\n /**\r\n * Toggle Panel\r\n * @memberof faceMasks\r\n * @param {number} panelId\r\n */\r\n function togglePanel(panelId) {\r\n $('#' + panelId).toggle();\r\n }\r\n\r\n function validInput(field){\r\n var isValid = true;\r\n\r\n if(field.Value == null || field.Value == undefined){\r\n isValid = false;\r\n }\r\n\r\n return isValid;\r\n }\r\n\r\n /**\r\n * Decrease field value by 1\r\n * @memberof faceMasks\r\n * @param {object} field \r\n */\r\n function numberDown(field){\r\n if(field.Value > 0){\r\n field.Value--;\r\n }\r\n } \r\n\r\n /**\r\n * Increase field value by 1\r\n * @memberof faceMasks\r\n * @param {object} field \r\n */\r\n function numberUp(field){\r\n field.Value++;\r\n }\r\n\r\n /**\r\n * Submit form\r\n * @memberof faceMasks\r\n */\r\n function submit(){\r\n if(scope.isOffline){\r\n scope.showPanel = \"offline\";\r\n }\r\n else{\r\n scope.showPanel = \"loading\";\r\n var DryStoreFound = scope.masksForm.Types.find(t => t.Type == \"A\").Fields.find(f => f.Title == \"Found\").Value;\r\n var DryStoreLeft = scope.masksForm.Types.find(t => t.Type == \"A\").Fields.find(f => f.Title == \"Left\").Value;\r\n\r\n var UniversalFound = scope.masksForm.Types.find(t => t.Type == \"B\").Fields.find(f => f.Title == \"Found\").Value;\r\n var UniversalLeft = scope.masksForm.Types.find(t => t.Type == \"B\").Fields.find(f => f.Title == \"Left\").Value;\r\n \r\n var FlightMaskReport = {\r\n FlightId : scope.masksForm.FlightId,\r\n DryStoreFound : DryStoreFound,\r\n DryStoreLeft : DryStoreLeft,\r\n UniversalFound : UniversalFound, \r\n UniversalLeft : UniversalLeft,\r\n LastUpdated : new Date()\r\n };\r\n \r\n FaceMasksFactory.submitFaceMaskReport(FlightMaskReport)\r\n .then(res => handleSubmitResponse(res, FlightMaskReport.LastUpdated));\r\n }\r\n }\r\n\r\n /**\r\n * Manage API response\r\n * @param {object} res \r\n * @param {date} timestamp \r\n */\r\n function handleSubmitResponse(res, timestamp) {\r\n if (res.success) {\r\n manageResponseMessage(\"success\", res.message);\r\n scope.LastUpdated = timestamp;\r\n $timeout(function () { scope.showPanel = \"masks\"; }, 6000);\r\n }\r\n else {\r\n manageResponseMessage(\"failure\", res.message);\r\n }\r\n }\r\n\r\n /**\r\n * Manage message alerts\r\n * @param {string} panelToShow \r\n * @param {string} message \r\n */\r\n function manageResponseMessage(panelToShow, message) {\r\n scope.submitMessage = message;\r\n scope.showPanel = panelToShow;\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: true,\r\n templateUrl: 'views/FaceMasks/faceMasks.tpl.html',\r\n scope: {\r\n flightId: '@',\r\n isOffline: '='\r\n },\r\n link: link\r\n }\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('FaceMasksFactory', FaceMasksFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FaceMasksFactory\r\n * @description \r\n * Get, Set and Submit Face Mask Info per flight.\r\n * @ngInject\r\n */\r\n function FaceMasksFactory(FlightFactory, $http, apiUrl) {\r\n var submitResponseObj = { success: false, message: '' }\r\n\r\n var service = {\r\n submitFaceMaskReport : submitFaceMaskReport\r\n };\r\n\r\n /**\r\n * Sends the Face Masks report\r\n * @memberof FaceMasksFactory\r\n * @param {object} flightMasks The Flight Face Masks Report\r\n * @returns {promise} submitResponseObj\r\n */\r\n function submitFaceMaskReport(flightMasks) {\r\n var objectToAdd = flightMasks;\r\n\r\n return $http.post(apiUrl + '/FaceMasks/', flightMasks, { 'Content-Type': 'application/json' })\r\n .then(res => saveReportSuccessCallBack(res, objectToAdd))\r\n .catch(res => saveReportFailedCallBack(res));\r\n }\r\n\r\n /**\r\n * The callback function upon successful submit\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} submitResponseObj\r\n */\r\n function saveReportSuccessCallBack(res, objectToAdd) {\r\n submitResponseObj.success = res.data.success;\r\n if (res.data.success) {\r\n //Attach face mask info to flight\r\n var flight = FlightFactory.getFlightFromStorage(objectToAdd.FlightId);\r\n flight.FaceMasks = objectToAdd;\r\n FlightFactory.updateFlight(flight);\r\n\r\n submitResponseObj.message = \"Success! Your input has been sent\";\r\n }\r\n else {\r\n submitResponseObj.message = res.data.errorMessage\r\n }\r\n return submitResponseObj;\r\n }\r\n\r\n /**\r\n * The callback function upon failure on submit\r\n * @returns {object} submitResponseObj\r\n */\r\n function saveReportFailedCallBack(res) {\r\n submitResponseObj.success = false;\r\n submitResponseObj.message = \"Oops! Something went wrong\"\r\n return submitResponseObj;\r\n }\r\n\r\n return service;\r\n }\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('FaqFactory',FaqFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FaqFactory\r\n * @description \r\n * Add, Update, Delete and Get FAQ.\r\n * @ngInject\r\n */\r\nfunction FaqFactory(GenericService) {\r\n\r\n /**\r\n * Initialize the FAQ\r\n * @memberof FaqFactory\r\n */\r\n\t\tfunction FAQ() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.FAQCategory = null;\r\n\t\t\tthis.FAQSubcategory = null;\r\n\t\t\tthis.Question = null;\r\n\t\t\tthis.Answer = null;\r\n\t\t\tthis.IsNew = null; //if FAQ is brand new\r\n\t\t\tthis.WasUpdated = null; //if FAQ was updated\r\n\t\t}\r\n\r\n\t\tvar objType = 'FAQItem';\r\n\t\tvar objCallback = FAQ; \r\n\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tgetFAQsFromStorage : getFAQsFromStorage,\r\n\t\t\tsetFAQsToStorage : setFAQsToStorage,\r\n\t\t\tsetFAQsFromServer : setFAQsFromServer\r\n\t\t};\r\n /**\r\n * Get FAQs\r\n * @memberof FaqFactory\r\n * @returns {Array} faqs \r\n */\r\n\t\tfunction getFAQsFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Set FAQs\r\n * @memberof FaqFactory\r\n * @param {array} FAQItem \r\n */\r\n\t\tfunction setFAQsToStorage(FAQItem) {\r\n\t\t\tGenericService.saveAll(FAQItem,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Delete FAQs\r\n * @memberof FaqFactory\r\n */\r\n\t\tfunction clearFAQsFromStorage() {\r\n\t\t\tGenericService.removeAll(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Set FAQs from api data\r\n * @memberof FaqFactory\r\n * @param {array} FAQItem \r\n */\r\n\t\tfunction setFAQsFromServer(newFAQs) {\r\n\r\n\t\t\tvar oldFAQs = getFAQsFromStorage();\r\n\r\n\t\t\tif(oldFAQs.length>0) {\r\n\r\n\t\t\t\tvar newPairList = [];\r\n\t\t\t\tvar oldPairList = [];\r\n\r\n\t\t\t\t//make a list with all new FAQ Question-Answer pair\r\n\t\t\t\tfor(var i=0; i -1) || (answer.indexOf(searchText) > -1)) && \r\n\t\t\t\t\t\t\t\t\t(!btnFilter || (btnFilter=='new' && oldFAQs[i].Subcategories[j].Pairs[k].IsNew) \r\n\t\t\t\t\t\t\t\t\t\t|| (btnFilter=='updated' && oldFAQs[i].Subcategories[j].Pairs[k].WasUpdated)))\r\n\t\t\t\t\t\t {\r\n\t\t\t\t\t\t\tshowCategory = true;\r\n\t\t\t\t\t\t\tshowSubCategory = true;\r\n\t\t\t\t\t\t\tSubcategory.Pairs.push(oldFAQs[i].Subcategories[j].Pairs[k]);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif (showSubCategory) {\r\n\t\t\t\t\t\tSubcategory.SubcategoryDescription = oldFAQs[i].Subcategories[j].SubcategoryDescription;\r\n\t\t\t\t\t\tCategory.Subcategories.push(Subcategory);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif(showCategory){\r\n\t\t\t\t\tCategory.CategoryDescription = oldFAQs[i].CategoryDescription;\r\n\t\t\t\t\tFAQ.push(Category);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t$scope.FAQItems = FAQ;\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('FaqsModalCtrl' ,FaqsModalCtrl)\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FaqsModalCtrl\r\n * @description \r\n * Shows an FAQ \r\n * @ngInject\r\n */\r\nfunction FaqsModalCtrl($scope, $uibModalInstance, pair) {\r\n $scope.pair = pair;\r\n $scope.cancel = cancel;\r\n\r\n /**\r\n * Close the modal\r\n * @memberof FaqsModalCtrl\r\n */\r\n function cancel() {\r\n $uibModalInstance.close('close');\r\n }\r\n}\r\n\r\n})();","(function () {\r\n\r\n a3_cabin_reports.directive('aimsCrewMemos', aimsCrewMemos);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name aimsCrewMemos\r\n * @restrict E\r\n * @description\r\n * Implementation of aimsCrewMemos\r\n * Initialize the Aims Crew Memos\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function aimsCrewMemos(AimsCrewMemosFactory) {\r\n function link($scope, element, attrs) {\r\n $scope.aimsCrewMemos = AimsCrewMemosFactory.getAimsCrewMemosByDate(attrs.date);\r\n \r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n templateUrl: \"views/directives/aimsCrewMemos.tpl.html\",\r\n scope: true,\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('AimsCrewMemosFactory', AimsCrewMemosFactory)\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AimsCrewMemosFactory\r\n * @description \r\n * Add, Update, Delete and Get Aims Crew Memos.\r\n * @ngInject\r\n */\r\nfunction AimsCrewMemosFactory(GenericService) {\r\n \r\n /**\r\n * Initialize the AircaftPositions\r\n * @memberof AircaftPositionsFactory\r\n */\r\n\t\tfunction AimsCrewMemos() {\r\n\t\t\tthis.Date = null;\r\n\t\t\tthis.Line = null;\r\n\t\t\tthis.OrderNo = null;\r\n\t\t\t\r\n \r\n this.GetId = GetId;\r\n\t\t}\r\n\t\t\t\t\r\n\t\tvar objType = 'AimsCrewMemos';\r\n\t\tvar objCallback = AimsCrewMemos; \r\n\t\t\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tgetAimsCrewMemosFromStorage : getAimsCrewMemosFromStorage,\r\n\t\t\tsetAimsCrewMemosToStorage : setAimsCrewMemosToStorage,\r\n\t\t\tclearAimsCrewMemosFactoryFromStorage : clearAimsCrewMemosFactoryFromStorage, \r\n\t\t\tgetAimsCrewMemosByDate : getAimsCrewMemosByDate,\r\n upsertAimsCrewMemos: upsertAimsCrewMemos,\r\n cleanOldAimsCrewMemos: cleanOldAimsCrewMemos\r\n\t\t};\r\n\r\n /**\r\n * Overide default get Id\r\n * @memberof AimsCrewMemosFactory\r\n * @returns {string} Id \r\n */\r\n\t\tfunction GetId() {\r\n\t\t\treturn this.Date;\r\n\t\t}\r\n\t\t\t\t\r\n \r\n \r\n /**\r\n * Get Aims Crew Memos\r\n * @memberof AimsCrewMemosFactory\r\n * @returns {Array} Aims Crew Memos\r\n */\r\n\t\tfunction getAimsCrewMemosFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save Aims Crew Memos to storage\r\n * @memberof AimsCrewMemosFactory\r\n * @param {Array} A list of Aims Crew Memos\r\n */\r\n\t\tfunction setAimsCrewMemosToStorage(aircaftPositions) {\r\n\t\t\tGenericService.saveAll(aircaftPositions,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Remove the Aims Crew Memos of the local storage\r\n * @memberof AimsCrewMemosFactory\r\n */\r\n\t\tfunction clearAimsCrewMemosFactoryFromStorage() {\r\n\t\t\tGenericService.removeAll(objType,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Get AimsCrewMemosFactory of this flight by date\r\n * @memberof AimsCrewMemosFactory\r\n * @returns {Object} AimsCrewMemosFactory\r\n */\r\n\t\tfunction getAimsCrewMemosByDate(date) {\r\n\t\t var crewMemos = getAimsCrewMemosFromStorage();\r\n \r\n var datesMemos = [];\r\n var arrayLength = crewMemos.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (crewMemos[i].GetId() == date) {\r\n\t\t\t\t\tdatesMemos.push(crewMemos[i]);\r\n\t\t\t\t\t\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn datesMemos;\r\n\t\t}\r\n\r\n /**\r\n * Upsert Aims Crew Memos\r\n * @memberof AimsCrewMemosFactory\r\n */\r\n function upsertAimsCrewMemos(aimsCrewMemos) {\r\n var newCrewMemos = aimsCrewMemos.map(x => x.Date);\r\n var aimsCrewMemosLS = this.getAimsCrewMemosFromStorage();\r\n aimsCrewMemosLS = aimsCrewMemosLS.filter(x => !newCrewMemos.includes(x.Date));\r\n var allAimsCrewMemos = aimsCrewMemosLS.concat(aimsCrewMemos);\r\n setAimsCrewMemosToStorage(allAimsCrewMemos);\r\n }\r\n\r\n /**\r\n * Clean Old Data\r\n * @memberof AimsCrewMemosFactory\r\n */\r\n\t\tfunction cleanOldAimsCrewMemos() {\r\n var now = moment();\r\n\t\t\tgetAimsCrewMemosFromStorage(function(crewMemos){\r\n\t\t\t\tvar memosToKeep = crewMemos.filter(function(item){\r\n var memoDate = moment(item.Date);\r\n\t\t\t\t\treturn now.diff(memoDate, 'days') < 5;\r\n\t\t\t\t});\r\n\t\t\t\t// keep only the memo with pending reports\r\n\t\t\t\tsetAimsCrewMemosToStorage(memosToKeep);\t\t\t\r\n\t\t\t})\r\n\t\t}\r\n \r\n // var dutyDate = moment(cabinReportLocalEdits[i].DutyDate);\r\n // if (cabinReportLocalEdits[i].Status !== 'stored' && now.diff(dutyDate, 'days') < 5) {\r\n\r\n\r\n\treturn service;\r\n\t}\r\n\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.factory('AircaftPositionsFactory', AircaftPositionsFactory)\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AircaftPositionsFactory\r\n * @description \r\n * Add, Update, Delete and Get AircaftPositions.\r\n * @ngInject\r\n */\r\n\tfunction AircaftPositionsFactory(GenericService) {\r\n\r\n /**\r\n * Initialize the AircaftPositions\r\n * @memberof AircaftPositionsFactory\r\n */\r\n\t\tfunction AircaftPositions() {\r\n\t\t\tthis.FlightId = null;\r\n\t\t\tthis.PreviousFlightNo = null;\r\n\t\t\tthis.PreviousStation = null;\r\n\t\t\tthis.PreviousSTA = null;\r\n\t\t\tthis.PreviousETA = null;\r\n\t\t\tthis.PreviousATA = null;\r\n\t\t\tthis.PreviousGATE = null;\r\n\t\t\tthis.PreviousSTAND = \"\";\r\n\t\t\tthis.PreviousSTANDArrival = \"\";\r\n\t\t\tthis.NextFlightNo = null;\r\n\t\t\tthis.NextStation = null;\r\n\t\t\tthis.NextSTD = null;\r\n\t\t\tthis.NextETD = null;\r\n\t\t\tthis.NextATD = null;\r\n\t\t\tthis.NextGATE = null;\r\n\t\t\tthis.NextSTAND = \"\";\r\n\t\t\tthis.NextSTANDArrival = \"\";\r\n\r\n\t\t\tthis.GetId = GetId;\r\n\t\t}\r\n\r\n\t\tvar objType = 'aircaftpositions';\r\n\t\tvar objCallback = AircaftPositions;\r\n\r\n\t\tvar service =\r\n\t\t{\r\n\t\t\tgetAircaftPositionsFromStorage: getAircaftPositionsFromStorage,\r\n\t\t\tsetAircaftPositionsToStorage: setAircaftPositionsToStorage,\r\n\t\t\tclearAircaftPositionsFromStorage: clearAircaftPositionsFromStorage,\r\n\t\t\tgetAircaftPositionsByFlightId: getAircaftPositionsByFlightId,\r\n\t\t\tupdateAircraftPositionsToStorage: updateAircraftPositionsToStorage,\r\n\t\t\tcleanOldData: cleanOldData\r\n\t\t};\r\n\r\n /**\r\n * Overide default get Id\r\n * @memberof AircaftPositionsFactory\r\n * @returns {number} Id \r\n */\r\n\t\tfunction GetId() {\r\n\t\t\treturn this.FlightId;\r\n\t\t}\r\n\r\n\r\n\r\n /**\r\n * Get messages\r\n * @memberof AircaftPositionsFactory\r\n * @returns {Array} Aircaft Positions \r\n */\r\n\t\tfunction getAircaftPositionsFromStorage() {\r\n\t\t\treturn GenericService.list(objType, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save Aircaft Positions to storage\r\n * @memberof AircaftPositionsFactory\r\n * @param {Array} messages A list of Aircaft Positions\r\n */\r\n\t\tfunction setAircaftPositionsToStorage(aircaftPositions) {\r\n\t\t\tGenericService.saveAll(aircaftPositions, objType, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Remove the Aircaft Positions of the local storage\r\n * @memberof AircaftPositionsFactory\r\n */\r\n\t\tfunction clearAircaftPositionsFromStorage() {\r\n\t\t\tGenericService.removeAll(objType, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get Aircaft Positions of this flight\r\n * @memberof AircaftPositionsFactory\r\n * @returns {Object} Aircaft Positions \r\n */\r\n\t\tfunction getAircaftPositionsByFlightId(flightId) {\r\n\t\t\treturn GenericService.get(flightId, objType, objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Update Aircraft Position to storage\r\n\t\t* @memberof AircaftPositionsFactory\r\n\t\t* @param {object} aircraftPositions Aircraft Positions\r\n\t\t*/\r\n\t\tfunction updateAircraftPositionsToStorage(aircraftPositions, flightId) {\r\n\t\t\tif (GenericService.get(flightId, objType, objCallback)){\r\n\t\t\t\tGenericService.save(aircraftPositions, objType, objCallback);\r\n\t\t\t}\r\n\t\t\telse if (aircraftPositions != null)\r\n\t\t\t\tGenericService.add(aircraftPositions, objType, objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n * Clean ls from old flights aircraft positions\r\n * @param {array} flights Synced flights\r\n */\r\n\t\t function cleanOldData(responseFlightIds){\r\n var previousAircaftPositions = getAircaftPositionsFromStorage();\r\n previousAircaftPositions = previousAircaftPositions.filter(x => responseFlightIds.includes(x.FlightId));\r\n setAircaftPositionsToStorage(previousAircaftPositions);\r\n }\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('AircraftDifferencesFactory', AircraftDifferencesFactory)\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AircraftDifferencesFactory\r\n * @description \r\n * Add, Update, Delete and Get AircraftDifferences.\r\n * @ngInject\r\n */\r\nfunction AircraftDifferencesFactory(GenericService,FlightFactory) {\r\n \r\n /**\r\n * Initialize the AircraftPositions\r\n * @memberof AircraftDifferencesFactory\r\n */\r\n\t\tfunction AircraftDifferences() {\r\n \r\n this.GetId = GetId;\r\n\t\t}\r\n \r\n\t\t\t\t\r\n\t\tvar objType = 'AircraftDifferences';\r\n\t\tvar objCallback = AircraftDifferences; \r\n\t\t\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tgetAircraftDifferencesFromStorage : getAircraftDifferencesFromStorage,\r\n\t\t\tsetAircraftDifferencesToStorage : setAircraftDifferencesToStorage,\r\n\t\t\tclearAircraftDifferencesFromStorage : clearAircraftDifferencesFromStorage,\r\n getAircraftDifferencesByFlightId : getAircraftDifferencesByFlightId,\r\n getAircraftDifferenceFromStorageByRegistration : getAircraftDifferenceFromStorageByRegistration,\r\n upsertAircraftDifferences : upsertAircraftDifferences\r\n\t\t};\r\n\r\n /**\r\n * Override default get Id\r\n * @memberof AircraftDifferencesFactory\r\n * @returns {number} Id \r\n */\r\n\t\tfunction GetId() {\r\n\t\t\treturn this.Registration;\r\n\t\t}\r\n\t\t\t\t\r\n \r\n \r\n /**\r\n * Get messages\r\n * @memberof AircraftDifferencesFactory\r\n * @returns {Array} Aircraft Differences \r\n */\r\n\t\tfunction getAircraftDifferencesFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n }\r\n \r\n function getAircraftDifferenceFromStorageByRegistration(registration) {\r\n return GenericService.get(registration,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save Aircraft Differences to storage\r\n * @memberof AircraftDifferencesFactory\r\n * @param {Array} messages A list of Aircraft Differences\r\n */\r\n\t\tfunction setAircraftDifferencesToStorage(aircraftDifferences) {\r\n\t\t\tGenericService.saveAll(aircraftDifferences,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Remove the Aircraft Differences of the local storage\r\n * @memberof AircraftDifferencesFactory\r\n */\r\n\t\tfunction clearAircraftDifferencesFromStorage() {\r\n\t\t\tGenericService.removeAll(objType,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Get Aircraft Differences of this flight\r\n * @memberof AircraftDifferencesFactory\r\n * @returns {Object} Aircraft Differences \r\n */\r\n\t\tfunction getAircraftDifferencesByFlightId(flightId) {\r\n var retVal= [];\r\n var flight = FlightFactory.getFlightFromStorage(flightId);\r\n if (!flight) {\r\n flight = FlightFactory.getLocalFlightFromStorage(flightId);\r\n }\r\n\r\n if (!flight) {\r\n return [];\r\n }\r\n \r\n var difference = getAircraftDifferenceFromStorageByRegistration(flight.AcTailNo);\r\n \r\n retVal = difference != null && difference.AircraftDifferences != null ? difference.AircraftDifferences : []; \r\n\r\n return retVal;\r\n\t\t\t// return GenericService.get(flightId,objType,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Upsert aircraft differences\r\n * @memberof AircraftDifferencesFactory\r\n */\r\n function upsertAircraftDifferences(aircraftDifferences) {\r\n var newAircraftDifferences = aircraftDifferences.map(x => x.Registration);\r\n var aircraftDifferencesLS = this.getAircraftDifferencesFromStorage();\r\n aircraftDifferencesLS = aircraftDifferencesLS.filter(x => !newAircraftDifferences.includes(x.Registration));\r\n var updatedAircraftDifferences = aircraftDifferencesLS.concat(aircraftDifferences);\r\n setAircraftDifferencesToStorage(updatedAircraftDifferences);\r\n } \r\n\r\n\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('crewRouteInfoPanel',crewRouteInfoPanel);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name crewRouteInfoPanel\r\n * @restrict EA\r\n * @description\r\n * Implementation of crewRouteInfoPanel\r\n *\r\n * Initialize the crew Route Info panel \r\n * @example\r\n * Usage:\r\n *
or \r\n * @ngInject\r\n */ \r\nfunction crewRouteInfoPanel($routeParams, $uibModal) {\r\n \r\n function link ($scope, element, attrs) { \r\n\r\n $scope.showDefaultView = showDefaultView;\r\n $scope.showFlightTimes = showFlightTimes; \r\n $scope.showCommercialView = showCommercialView;\r\n $scope.showDelaysView = showDelaysView;\r\n $scope.showHiddenRows = false;\r\n $scope.toggleshowHiddenRows = toggleshowHiddenRows;\r\n $scope.defaultColumns = true;\r\n $scope.commercialColumns = false;\r\n $scope.timesColumns = false;\r\n $scope.delaysColumns = false;\r\n $scope.crewMeals = '';\r\n $scope.showDate = showDate;\r\n $scope.openCrewContactsModal = openCrewContactsModal;\r\n\r\n function showDefaultView() {\r\n $scope.defaultColumns = true;\r\n $scope.timesColumns = false;\r\n $scope.commercialColumns = false;\r\n $scope.delaysColumns = false;\r\n }\r\n\r\n function showFlightTimes() { \r\n $scope.defaultColumns = false;\r\n $scope.timesColumns = true;\r\n $scope.commercialColumns = false;\r\n $scope.delaysColumns = false;\r\n }\r\n\r\n function showCommercialView() {\r\n $scope.defaultColumns = false;\r\n $scope.timesColumns = false;\r\n $scope.commercialColumns = true;\r\n $scope.delaysColumns = false;\r\n }\r\n \r\n function showDelaysView(){\r\n $scope.defaultColumns = false;\r\n $scope.timesColumns = false;\r\n $scope.commercialColumns = false;\r\n $scope.delaysColumns = true;\r\n }\r\n \r\n function toggleshowHiddenRows(){\r\n if($scope.crewRouteInfoPanel.hasAircraftPositions){\r\n $scope.showHiddenRows =! $scope.showHiddenRows;\r\n }\r\n }\r\n\r\n function showDate(acRouteSTD, flightSTD){\r\n var datediff = moment(acRouteSTD).startOf('day').diff(moment(flightSTD).startOf('day'), 'days');\r\n return datediff != 0;\r\n }\r\n\r\n /**\r\n * Open dialog with the crew details\r\n * @memberof BucketCtrl\r\n */\r\n function openCrewContactsModal(crewInfo, selectedflightid, selectedFlightNo) { \r\n if(crewInfo && crewInfo.length > 0){\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/CrewRoute/dlgCrewContacts.html',\r\n controller: 'CrewContactsModalCtrl',\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n crewInfo: function () { return crewInfo; },\r\n selectedflightid: function () { return selectedflightid; },\r\n selectedFlightNo: function () { return selectedFlightNo; }\r\n }\r\n });\r\n } \r\n }\r\n }\r\n return {\r\n\t\t\trestrict: 'EA',\r\n\t\t\tterminal: true,\r\n templateUrl: 'views/directives/crewRouteInfoPanel.tpl.html',\r\n\t\t\tscope : false,\r\n link: link \r\n }\r\n}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('FlightConfigCtrl',FlightConfigCtrl)\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FlightConfigCtrl\r\n * @description \r\n * Set the ETA of the flight\r\n * @ngInject\r\n */\r\nfunction FlightConfigCtrl($scope,$uibModalInstance,flight,FlightFactory){\r\n\r\n\t\t$scope.cancel = cancel;\r\n\t\t$scope.save = save;\r\n\t\t$scope.flightETA = new Date(flight.ETA? flight.ETA : flight.ScheduledArrival);\r\n\r\n /**\r\n * Save the new ETA\r\n * @memberof FlightConfigCtrl\r\n */\r\n\t\tfunction save() {\r\n\t\t\tif ($scope.flightETA){\r\n\t\t\t\tvar ETAdate = $scope.flightETA;\r\n\t\t\t\tvar STDdate =new Date(flight.ScheduledDeparture);\r\n\r\n var ETAtimestamp = ETAdate.getTime();\r\n\t\t\t\tvar STDtimestamp = STDdate.getTime();\r\n \r\n\t\t\t\tETAdate.setUTCFullYear(STDdate.getUTCFullYear());\r\n\t\t\t\tETAdate.setUTCMonth(STDdate.getUTCMonth());\r\n\t\t\t\tETAdate.setUTCDate(STDdate.getUTCDate());\r\n\r\n\t\t\t\tif(ETAtimestamp x.FlightId);\r\n var flightDelaysLS = this.getFlightDelaysFromStorage();\r\n flightDelaysLS = flightDelaysLS.filter(x => !newFLightIds.includes(x.FlightId));\r\n var allFlightDelays = flightDelaysLS.concat(newflightDelays);\r\n setFlightDelaysToStorage(allFlightDelays);\r\n }\r\n\r\n\t\t/**\r\n * Clean Old Data\r\n * @memberof FlightDelaysFactory\r\n * @param {Array} pendingFlightIds FlightIds with pending reports\r\n */\r\n\t\tfunction cleanOldFlightDelays(pendingFlightIds) {\r\n\t\t\tvar now = moment();\r\n\t\t\tgetFlightDelaysFromStorage(function(flightDelays){\r\n\t\t\t\tvar pendingFlightDelays = flightDelays.filter(function(item){\r\n\t\t\t\t\tvar date = moment(item.FlightDate);\r\n\t\t\t\t\treturn pendingFlightIds.includes(item.FlightId) || now.diff(date, 'days') < 5;\r\n\t\t\t\t});\r\n\t\t\t\t// keep only the FlightDelays with pending reports\r\n\t\t\t\tsetFlightDelaysToStorage(pendingFlightDelays);\t\t\t\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.controller('FlightGateCtrl', FlightGateCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FlightGateCtrl\r\n * @description \r\n * View all flight connections and search for more possible connecting flights\r\n * @ngInject\r\n */\r\n\tfunction FlightGateCtrl($scope, $uibModalInstance, flight, FlightGateFactory, SyncLogFactory, FlightFactory, PaxInfoFactory) {\r\n\r\n\t\tvar flightId = flight.FlightId;\r\n\t\tvar items = [];\r\n\t\tvar syncLog = SyncLogFactory.getSyncLog();\r\n\t\tvar distinct_gates = [];\r\n\t\tvar searchFilters = flight.FlightsFilters;\r\n\t\tvar gates = FlightGateFactory.getAfterSTDFromStorage(flight.ScheduledDeparture, flight.Arrival);\r\n\r\n\t\t$scope.isConnectedFlightClose = isConnectedFlightClose;\r\n\t\t$scope.TimeDifference = TimeDifference;\r\n\t\t$scope.IsOld = IsOld;\r\n\t\t$scope.searchText = '';\r\n\t\t$scope.addFilter = addFilter;\r\n\t\t$scope.removeFilter = removeFilter;\r\n\t\t$scope.cancel = cancel;\r\n\t\t$scope.filters = searchFilters;\r\n\r\n\t\tPaxInfoFactory.getPaxInfoFromStorage(flight.FlightId, function (paxInfo) {\r\n\t\t\tif (paxInfo) {\r\n\t\t\t\titems = paxInfo.TotalFlights;\r\n\t\t\t\t$scope.items = items.sort(function (a, b) { return (new Date(a.STD).getTime()) - (new Date(b.STD).getTime()) });\r\n\r\n\t\t\t\tfor (var i = 0; i < gates.length; i++) {\r\n\t\t\t\t\tvar exists = false;\r\n\t\t\t\t\tfor (var j = 0; j < items.length; j++) {\r\n\t\t\t\t\t\tif (items[j].FlightNo == gates[i].FlightNo && items[j].Dep == gates[i].Dep) {\r\n\t\t\t\t\t\t\tvar connectingTime = new Date(items[j].STD_lcl);\r\n\t\t\t\t\t\t\tvar flightGateTime = new Date(gates[i].STD);\r\n\t\t\t\t\t\t\tif (connectingTime.getTime() == flightGateTime.getTime()) {\r\n\t\t\t\t\t\t\t\tif ((!items[j].Codeshares) || items[j].Codeshares.length == 0) {\r\n\t\t\t\t\t\t\t\t\titems[j].Codeshares == gates[i].Codeshares;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\texists = true;\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (!exists) {\r\n\t\t\t\t\t\tvar distinct_gate =\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tFlightNo: gates[i].FlightNo, Gate: gates[i].DepGate,\r\n\t\t\t\t\t\t\tArr: gates[i].Arrival, STD_lcl: gates[i].STD_lcl,\r\n\t\t\t\t\t\t\tSTD: gates[i].STD,\r\n\t\t\t\t\t\t\tpax: null, Codeshares: gates[i].Codeshares,\r\n\t\t\t\t\t\t\tUpdatedDate: gates[i].lastUpdate\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tdistinct_gates.push(distinct_gate);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\tvar flightArrivalTime = new Date(flight.ScheduledArrival).getTime();\r\n\t\t$scope.hasGates = distinct_gates.length > 0;\r\n\t\t$scope.flightETA = flight.ETA ? new Date(flight.ETA).getTime() : flightArrivalTime;\r\n\r\n\t\tapplyFilter();\r\n /**\r\n * Calculates if a connecting flight is departs sort time after fligths arrival \r\n * @memberof FlightGateCtrl\r\n * @param {string} connection Connection STD\r\n * @return {string} cssClass\r\n */\r\n\t\tfunction isConnectedFlightClose(connection) {\r\n\r\n\t\t\tif (!connection) {\r\n\t\t\t\treturn '';\r\n\t\t\t}\r\n\r\n\t\t\tvar connFlightDate = new Date(connection).getTime();\r\n\r\n\t\t\tif ($scope.flightETA > connFlightDate)\r\n\t\t\t\treturn '';\r\n\r\n\t\t\tif ((connFlightDate - $scope.flightETA) < 3600001) {\r\n\t\t\t\treturn 'bg-bisque';\r\n\t\t\t}\r\n\r\n\t\t\tif ((connFlightDate - $scope.flightETA) < 6480000) {\r\n\t\t\t\treturn 'bg-cornsilk';\r\n\t\t\t}\r\n\r\n\t\t\treturn '';\r\n\t\t}\r\n\r\n /**\r\n * Returns the time difference\r\n * @memberof FlightGateCtrl\r\n * @param {string} time Connection STD\r\n * @return {string} timeDifference\r\n */\r\n\t\tfunction TimeDifference(time) {\r\n\r\n\t\t\tvar timeString = '';\r\n\t\t\tvar sign = '';\r\n\t\t\tvar dayString = null;\r\n\t\t\tif (time) {\r\n\t\t\t\tvar connFlightDate = new Date(time);\r\n\t\t\t\tvar ms = connFlightDate.getTime() - $scope.flightETA; // this is a time in milliseconds\r\n\t\t\t\tif (ms < 0) {\r\n\t\t\t\t\tms = -ms;\r\n\t\t\t\t\tsign = \"-\";\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar days = Math.floor(ms / (24 * 60 * 60 * 1000));\r\n\t\t\t\tdays = days < 0 ? days + 1 : days;\r\n\t\t\t\tvar daysms = ms % (24 * 60 * 60 * 1000);\r\n\t\t\t\tvar hours = Math.floor((daysms) / (60 * 60 * 1000));\r\n\t\t\t\tvar hoursms = ms % (60 * 60 * 1000);\r\n\t\t\t\tvar minutes = Math.floor((hoursms) / (60 * 1000));\r\n\t\t\t\ttimeString = '' + sign + (hours > 0 ? (\"0\" + hours).substr(-2) + \":\" : '') + (\"0\" + minutes).substr(-2) + '\\'' + '';\r\n\t\t\t\tdayString = ' ' + days + 'd';\r\n\t\t\t}\r\n\t\t\treturn timeString + ((days && days != 0) ? dayString : '');\r\n\t\t}\r\n\r\n /**\r\n * Checks if the data are new\r\n * @memberof FlightGateCtrl\r\n * @param {string} time timestamp\r\n * @return {boolean} IsOld\r\n */\r\n\t\tfunction IsOld(time) {\r\n\t\t\tIsOld = false;\r\n\t\t\tif (time) {\r\n\t\t\t\tvar now = new Date();\r\n\t\t\t\tvar timeDate = new Date(time);\r\n\t\t\t\tvar diff = now.getTime() - timeDate.getTime();\r\n\t\t\t\tif (diff > 3600000) {\r\n\t\t\t\t\tIsOld = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn IsOld;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Apply given filters to show connectings flights\r\n\t\t* @memberof FlightGateCtrl\r\n\t\t*/\r\n\t\tfunction applyFilter() {\r\n\t\t\tvar newFlightgates = [];\r\n\t\t\tif (searchFilters.length > 0) {\r\n\t\t\t\tfor (var i = 0; i < distinct_gates.length; i++) {\r\n\t\t\t\t\tfor (var j = 0; j < searchFilters.length; j++) {\r\n\t\t\t\t\t\tvar row = distinct_gates[i].FlightNo + \",\" + distinct_gates[i].Codeshares.toString();\r\n\t\t\t\t\t\tif (row.indexOf(searchFilters[j].toString()) >= 0) {\r\n\t\t\t\t\t\t\tnewFlightgates.push(distinct_gates[i]);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t$scope.gates = newFlightgates.sort(function (a, b) { return (new Date(a.STD).getTime()) - (new Date(b.STD).getTime()) });\r\n\t\t}\r\n\r\n /**\r\n * Add a filter\r\n * @memberof FlightGateCtrl\r\n * @param {string} searchText Search text\r\n */\r\n\t\tfunction addFilter(searchText) {\r\n\t\t\tif (searchText.trim().length > 0) {\r\n\t\t\t\tvar exists = false;\r\n\t\t\t\tfor (var i = 0; i < $scope.filters.length; i++) {\r\n\t\t\t\t\tif ($scope.filters[i] == searchText.toString().toUpperCase()) {\r\n\t\t\t\t\t\texists = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (!exists) {\r\n\t\t\t\t\tvar flight = FlightFactory.getFlightFromStorage(flightId);\r\n\t\t\t\t\tsearchFilters.push(searchText.toString().toUpperCase());\r\n\t\t\t\t\tflight.FlightsFilters = searchFilters;\r\n\t\t\t\t\tFlightFactory.updateFlight(flight);\r\n\t\t\t\t\t$scope.filters = searchFilters;\r\n\t\t\t\t}\r\n\t\t\t\t$scope.searchText = \"\";\r\n\t\t\t\tapplyFilter();\r\n\t\t\t}\r\n\t\t}\r\n\r\n /**\r\n * Remove a filter\r\n * @memberof FlightGateCtrl\r\n * @param {item} string filter\r\n */\r\n\t\tfunction removeFilter(item) {\r\n\t\t\tvar flight = FlightFactory.getFlightFromStorage(flightId);\r\n\t\t\tvar index = searchFilters.indexOf(item);\r\n\t\t\tsearchFilters.splice(index, 1);\r\n\t\t\tflight.FlightsFilters = searchFilters;\r\n\t\t\tFlightFactory.updateFlight(flight);\r\n\t\t\t$scope.filters = searchFilters;\r\n\t\t\tapplyFilter();\r\n\t\t}\r\n\r\n /**\r\n * Close the modal\r\n * @memberof FlightGateCtrl\r\n */\r\n\t\tfunction cancel() {\r\n\t\t\t$uibModalInstance.close($scope.gates);\r\n\t\t}\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('FlightGateFactory',FlightGateFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightGateFactory\r\n * @description \r\n * Add, Update, Delete and Get Flight Gates.\r\n * @ngInject\r\n */ \r\nfunction FlightGateFactory(GenericService){\r\n \r\n /**\r\n * Initialize the FlightGate\r\n * @memberof FlightGateFactory\r\n */\r\n\t\tfunction FlightGate() {\r\n\t\t\tthis.FlightDate = null;\r\n\t\t\tthis.Codeshares = [];\r\n\t\t\tthis.FlightNo = null;\r\n\t\t\tthis.Departure = null;\r\n\t\t\tthis.Arrival = null;\r\n\t\t\tthis.STD = null;\r\n\t\t\tthis.STA = null;\r\n\t\t\tthis.ETD = null;\r\n\t\t\tthis.ETA = null;\r\n\t\t\tthis.STD_Diff = null;\r\n\t\t\tthis.STA_Diff = null;\r\n\t\t\tthis.STD_lcl = null;\r\n\t\t\tthis.STA_lcl = null;\r\n\t\t\tthis.ETD_lcl = null;\r\n\t\t\tthis.ETA_lcl = null;\r\n\t\t\tthis.DepGate = null;\r\n\t\t\tthis.DepStand = null;\r\n\t\t\tthis.AcType = null;\r\n\t\t\tthis.lastUpdate = null;\r\n\t\t\t//net fields used to hold values before latest update\r\n\t\t\tthis.previousUpdate = null;\r\n\t\t\tthis.previousGate = null;\r\n\t\t\tthis.previousSTD = null;\r\n\t\t\tthis.previousSTD_lcl = null;\r\n\t\t\tthis.previousSTD_Diff = null;\r\n\t\t\tthis.previousSTA = null;\r\n\t\t\tthis.previousSTA_lcl = null;\r\n\t\t\tthis.previousSTA_Diff = null;\r\n\t\t\t//object functions\r\n\t\t\tthis.getRoute=getRoute;\r\n\t\t\tthis.dtSTD=dtSTD\r\n\t\t\tthis.dtSTA=dtSTA;\r\n\t\t\tthis.dtETD=dtETD;\r\n\t\t\tthis.dtETA=dtETA;\r\n\t\t\tthis.dtSTD_lcl=dtSTD_lcl;\r\n\t\t\tthis.dtSTA_lcl=dtSTA_lcl;\r\n\t\t\tthis.dtETD_lcl=dtETD_lcl;\r\n\t\t\tthis.dtETA_lcl=dtETA_lcl;\r\n\t\t\tthis.dateSTD=dateSTD;\r\n\t\t\tthis.timeSTD=timeSTD;\r\n\t\t\tthis.timeSTA=timeSTA;\r\n\t\t\tthis.timeETD=timeETD;\r\n\t\t\tthis.timeETA=timeETA;\r\n\t\t\tthis.timeSTD_lcl=timeSTD_lcl;\r\n\t\t\tthis.timeSTA_lcl=timeSTA_lcl;\r\n\t\t\tthis.timeETD_lcl=timeETD_lcl;\r\n\t\t\tthis.timeETA_lcl=timeETA_lcl;\r\n\t\t\tthis.hasETD=hasETD;\r\n\t\t\tthis.hasETA=hasETA;\r\n\t\t\tthis.depDelay=depDelay;\r\n\t\t\tthis.arrDelay=arrDelay;\r\n\t\t\tthis.setUpdatedNow=setUpdatedNow;\r\n\t\t\tthis.gateChanged=gateChanged;\r\n\t\t\tthis.stdChanged=stdChanged;\r\n\t\t\tthis.staChanged=staChanged;\r\n\t\t\tthis.stdDiffChanged=stdDiffChanged;\r\n\t\t\tthis.staDiffChanged=staDiffChanged;\r\n\t\t\tthis.toString=toString;\r\n\t\t\tthis.changesToString=changesToString;\r\n\t\t\tthis.getKey=getKey;\r\n\t\t}\r\n\t\t\t \r\n\t\tvar objType = 'FlightGates';\r\n\t\tvar objCallback = FlightGate; \r\n\t\t\t\t\r\n\t\tvar service = {\r\n\t\t\tprocessUpdatedData : processUpdatedData,\r\n\t\t\tgetFromStorage : getFromStorage,\r\n\t\t\tgetAfterSTDFromStorage : getAfterSTDFromStorage,\r\n\t\t\tsetToStorage : setToStorage\r\n\t\t}\r\n\t\t\r\n\t\t//Object functions\r\n\t\tfunction getRoute() {\r\n\t\t\tif (this.Departure == null && this.Arrival == null) return '-null-';\r\n\t\t\telse return (this.Departure || '?') + '-' + (this.Arrival || '?');\r\n\t\t}\r\n\t\t\t\t\r\n /**\r\n * Transform STD iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\r\n\t\tfunction dtSTD(){\r\n\t\t\treturn stringIsoToDateTime(this.STD);\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Transform STA iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\r\n\t\tfunction dtSTA(){\r\n\t\t\treturn stringIsoToDateTime(this.STA);\r\n\t\t}\r\n\r\n /**\r\n * Transform ETD iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\r\n\t\tfunction dtETD(){\r\n\t\t\treturn stringIsoToDateTime(this.ETD);\r\n\t\t}\r\n /**\r\n * Transform ETA iso string to date\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\r\n\t\tfunction dtETA(){\r\n\t\t\treturn stringIsoToDateTime(this.ETA);\r\n\t\t}\t\t\t\r\n /**\r\n * Transform local STD iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\t\t\r\n\t\tfunction dtSTD_lcl(){\r\n\t\t\treturn stringIsoToDateTime(this.STD_lcl);\r\n\t\t}\r\n /**\r\n * Transform local STA iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\t\r\n\t\tfunction dtSTA_lcl(){\r\n\t\t\treturn stringIsoToDateTime(this.STA_lcl);\r\n\t\t}\r\n /**\r\n * Transform local ETD iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\r\n\t\tfunction dtETD_lcl(){\r\n\t\t\treturn stringIsoToDateTime(this.ETD_lcl);\r\n\t\t}\r\n /**\r\n * Transform local ETA iso string to datetime\r\n * @memberof FlightGateFactory\r\n * @return {object} date\r\n */\r\n\t\tfunction dtETA_lcl(){\r\n\t\t\treturn stringIsoToDateTime(this.ETA_lcl);\r\n\t\t}\t\r\n /**\r\n * Transform STD iso string to date string\r\n * @memberof FlightGateFactory\r\n * @return {string} date\r\n */\r\n function dateSTD(){\r\n\t\t\treturn stringIsoToDateString(this.STD);\r\n\t\t}\r\n /**\r\n * Transform STD iso string to time string \r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\r\n\t\tfunction timeSTD(){\r\n\t\t\treturn stringIsoToTimeString(this.STD);\r\n\t\t}\r\n /**\r\n * Transform STA iso string to time string \r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\r\n\t\tfunction timeSTA(){\r\n\t\t\treturn stringIsoToTimeString(this.STA);\r\n\t\t}\r\n /**\r\n * Transform ETD iso string to time string\r\n * @memberof FlightGateFactory\r\n * @return {object} time\r\n */\r\n\t\tfunction timeETD(){\r\n\t\t\treturn stringIsoToTimeString(this.ETD);\r\n\t\t}\r\n /**\r\n * Transform ETA iso string to time string\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\r\n\t\tfunction timeETA(){\r\n\t\t\treturn stringIsoToTimeString(this.ETA);\r\n\t\t}\r\n /**\r\n * Transform STD iso string to local time string\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\r\n\t\tfunction timeSTD_lcl(){\r\n\t\t\treturn stringIsoToTimeString(this.STD_lcl);\r\n\t\t}\r\n /**\r\n * Transform local STA iso string to string time\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\r\n\t\tfunction timeSTA_lcl(){\r\n\t\t\treturn stringIsoToTimeString(this.STA_lcl);\r\n\t\t}\r\n /**\r\n * Transform local ETD iso string to time string\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\r\n\t\tfunction timeETD_lcl(){\r\n\t\t\treturn stringIsoToTimeString(this.ETD_lcl);\r\n\t\t}\r\n /**\r\n * Transform local ETA iso string to time\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\r\n\t\tfunction timeETA_lcl(){\r\n\t\t\treturn stringIsoToTimeString(this.ETA_lcl);\r\n\t\t}\r\n\r\n /**\r\n * check if gate has ETD\r\n * @memberof FlightGateFactory\r\n * @return {boolean} hasETD\r\n */\r\n\t\tfunction hasETD(){\r\n\t\t\tif (this.ETD && this.STD != this.ETD && this.dtSTD() < this.dtETD())\r\n\t\t\t\treturn true;\r\n\t\t\telse\r\n\t\t\t\treturn false;\r\n\t\t}\r\n\r\n /**\r\n * check if gate has ETA\r\n * @memberof FlightGateFactory\r\n * @return {boolean} hasETA\r\n */\r\n\t\tfunction hasETA(){\r\n\t\t\treturn (this.ETA && this.STA != this.ETA && this.dtSTA() < this.dtETA())\r\n\t\t}\r\n\r\n /**\r\n * Return departure delay\r\n * @memberof FlightGateFactory\r\n * @return {string} STD_Diff\r\n */\r\n\t\tfunction depDelay(){\r\n\t\t\tif (this.hasETD() && this.STD_Diff && this.STD_Diff > 0)\r\n\t\t\t\treturn this.STD_Diff;\r\n\t\t\telse\r\n\t\t\t\treturn null;\r\n\t\t}\r\n \r\n /**\r\n * Return arrival delay\r\n * @memberof FlightGateFactory\r\n * @return {boolean} STA_Diff\r\n */\r\n\t\tfunction arrDelay(){\r\n\t\t\tif (this.hasETA() && this.STA_Diff && this.STA_Diff > 0)\r\n\t\t\t\treturn this.STA_Diff;\r\n\t\t\telse\r\n\t\t\t\treturn null;\r\n\t\t}\r\n\r\n /**\r\n * record the current time as the lastUpdate of the object\r\n * @memberof FlightGateFactory\r\n */\r\n\t\tfunction setUpdatedNow(){\r\n\t\t\tthis.lastUpdate = new Date();\r\n\t\t\tif (this.DepGate == null)\r\n\t\t\t\tthis.DepGate='';\r\n\t\t}\r\n\r\n /**\r\n * Check if the gate has changed since the last update\r\n * @memberof FlightGateFactory\r\n * @return {boolean} gateChanged\r\n */\r\n\t\tfunction gateChanged(){\r\n\t\t\tif (!this.previousGate)\r\n\t\t\t\treturn false;\r\n\t\t\telse\r\n\t\t\t\treturn true;\r\n\t\t}\r\n\r\n /**\r\n * Check if the STD has changed since the last update\r\n * @memberof FlightGateFactory\r\n * @return {boolean} stdChanged\r\n */\r\n\t\tfunction stdChanged(){\r\n\t\t\tif (!this.previousSTD)\r\n\t\t\t\treturn false;\r\n\t\t\telse\r\n\t\t\t\treturn true;\r\n\t\t}\r\n\r\n /**\r\n * Check if the STA has changed since the last update\r\n * @memberof FlightGateFactory\r\n * @return {boolean} staChanged\r\n */\r\n\t\tfunction staChanged(){\r\n\t\t\tif (!this.previousSTA)\r\n\t\t\t\treturn false;\r\n\t\t\telse\r\n\t\t\t\treturn true;\r\n\t\t}\r\n\r\n /**\r\n * Check if the STD diff has changed since the last update\r\n * @memberof FlightGateFactory\r\n * @return {boolean} stdDiffChanged\r\n */\r\n\t\tfunction stdDiffChanged(){\r\n\t\t\tif (!this.previousSTD_Diff)\r\n\t\t\t\treturn false;\r\n\t\t\telse\r\n\t\t\t\treturn true;\r\n\t\t}\r\n\r\n /**\r\n * Check if the STA diff has changed since the last update\r\n * @memberof FlightGateFactory\r\n * @return {boolean} staDiffChanged\r\n */\r\n\t\tfunction staDiffChanged(){\r\n\t\t\tif (!this.previousSTA_Diff)\r\n\t\t\t\treturn false;\r\n\t\t\telse\r\n\t\t\t\treturn true;\r\n\t\t}\r\n\r\n /**\r\n * Print the flight gate info\r\n * @memberof FlightGateFactory\r\n * @return {string} toSting\r\n */ \r\n\t\tfunction toString(){\r\n\t\t\tvar s=this.dateSTD() + ' ' + this.FlightNo;\r\n\t\t\ts+=' ' + this.Departure + '-' + this.Arrival;\r\n\t\t\ts+=' ' + (this.hasETD() ? 'ETD'+this.timeETD_lcl()+(this.depDelay() ? '[+'+this.depDelay()+'\\']' : '') : 'STD'+this.timeSTD_lcl());\r\n\t\t\ts+='->' + (this.hasETA() ? 'ETA'+this.timeETA_lcl() + '[' + (this.STA_Diff>0 ? '+' : '-')+this.STA_Diff + '\\']' : 'STA'+this.timeSTA_lcl());\r\n\t\t\ts+=(this.DepGate ? ' Gate: ' + this.DepGate : '');\r\n\t\t\treturn s;\r\n\t\t}\r\n \r\n /**\r\n * Show all the changes of the flight gates\r\n * @memberof FlightGateFactory\r\n * @return {string} toSting\r\n */ \r\n\t\tfunction changesToString(){\r\n\t\t\tvar s='';\r\n\t\t\tif (this.stdChanged())\r\n\t\t\t\ts+='STD: ' + stringIsoToTimeString(this.previousSTD) + ' -> ' + this.timeSTD();\r\n\t\t\tif (self.stdDiffChanged())\r\n\t\t\t\ts+=(s=='' ? '' : ', ')+'departure delay: '+this.previousSTD_Diff + ' -> ' + this.STD_Diff;\r\n\t\t\tif (self.staChanged())\r\n\t\t\t\ts+=(s=='' ? '' : ', ')+'STA: ' + stringIsoToTimeString(this.previousSTA) + ' -> ' + this.timeSTA();\r\n\t\t\tif (self.staDiffChanged())\r\n\t\t\t\ts+=(s=='' ? '' : ', ')+'arrival delay: '+this.previousSTA_Diff + ' -> ' + this.STA_Diff;\r\n\t\t\tif (self.gateChanged())\r\n\t\t\t\ts+=(s=='' ? '' : ', ')+' gate: '+this.previousGate + ' -> ' + this.DepGate;\r\n\t\t\treturn s;\r\n\t\t}\r\n\r\n /**\r\n * returns a string with all the fields uniquely defining a flight, concatenated\r\n * @memberof FlightGateFactory\r\n * @return {string} key\r\n */ \r\n\t\tfunction getKey(){\r\n\t\t\tvar s = this.FlightDate + '|' + this.FlightNo + '|' + this.Departure + '-' + this.Arrival;\r\n\t\t\treturn s;\r\n\t\t}\r\n\t\t\r\n //Service functions\r\n /**\r\n * Transform iso datetime string to date time Object\r\n * @memberof FlightGateFactory\r\n * @return {Object} DateTime\r\n */\r\n\t\tfunction stringIsoToDateTime(str){\r\n\t\t\tvar dt=null;\r\n\t\t\ttry{\r\n\t\t\t\tif (str){\r\n\t\t\t\t\t//replace T in order to avoid browser converting datetime to browser's timezone\r\n\t\t\t\t\t//eg 2016-05-17T23:04:00 would be converted to Wed May 18 2016 02:04:00 GMT+0300 (GTB Daylight Time) when we want it to be Tue May 17 2016 23:04:00 GMT+0300 (GTB Daylight Time)\r\n\t\t\t\t\tstr = str.replace('T', ' ');\r\n\t\t\t\t\tdt=new Date(str);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tcatch(e){}\r\n\t\t\treturn dt;\r\n\t\t}\r\n /**\r\n * Transform iso datetime string to date string\r\n * @memberof FlightGateFactory\r\n * @return {string} date\r\n */\r\n\t\tfunction stringIsoToDateString(str){\r\n\t\t\tvar dt= stringIsoToDateTime(str);\r\n\t\t\tvar s=null;\r\n\t\t\tif (dt){\r\n\t\t\t\tvar year=dt.getFullYear();\r\n\t\t\t\tvar month=dt.getMonth()+1;\r\n\t\t\t\tvar day=dt.getDate();\r\n\t\t\t\ts=(day < 10 ? '0' : '')+day+'.'+(month < 10 ? '0' : '')+month+'.'+year;\r\n\t\t\t}\r\n\t\t\treturn s;\r\n\t\t}\r\n /**\r\n * Transform iso datetime string to time string\r\n * @memberof FlightGateFactory\r\n * @return {string} time\r\n */\r\n\t\tfunction stringIsoToTimeString(str){\r\n\t\t\tvar dt=stringIsoToDateTime(str);\r\n\t\t\tvar s=null;\r\n\t\t\tif (dt){\r\n\t\t\t\tvar hour=dt.getHours();\r\n\t\t\t\tvar min=dt.getMinutes();\r\n\t\t\t\ts=(hour < 10 ? '0' : '')+hour+':'+(min<10 ? '0' : '')+min+'';\r\n\t\t\t}\r\n\t\t\treturn s;\r\n\t\t}\r\n\t\t\r\n /**\r\n * Process updated list of fligths 'gates' and store them.Before storing them, we need to identify changes in Gates and in ETD/ETA to notify customers when required. \r\n * @memberof FlightGateFactory\r\n */\r\n\t\tfunction processUpdatedData(data){\r\n\t\t\t//Update List\r\n\t\t\tvar list= fromObjectList(data);\r\n\t\t\t\r\n\t\t\t//Original List\r\n\t\t\tvar listPrevious=getFromStorage();\r\n\t\t\t\r\n\t\t\t//Search each \"new\" flight in the new list, and check if it has been modified since last update\r\n\t\t\tif (list && list.length > 0)\r\n\t\t\t{\r\n\t\t\t\tvar flight,flightPrevious, hasChanged;\r\n\t\t\t\tvar previousLength=listPrevious.length;\r\n\t\t\t\tfor(var i=0;i0){\r\n\t\t\t\t\t\tfor(var p=0;p=date || (dateETD !=null && dateETD.getTime()>=date )) && dep==flightgates[i].Departure && \r\n\t\t\t\t\t//check only for 2 days later\r\n\t\t\t\t\t(dateSTD.getTime()<=(date+172800000))) {\r\n\t\t\t\t\tnewFlightgates.push(flightgates[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn newFlightgates;\r\n\t\t}\r\n \r\n /**\r\n * Set flightgates from storage\r\n * @memberof FlightGateFactory\r\n * @param {array} data\r\n */\t\r\n\t\tfunction setToStorage(data){\r\n\t\t\tGenericService.saveAll(data,objType,objCallback);\r\n\t\t}\r\n\t\t\r\n /**\r\n * Extend an array of Objects from the default FlightGate Object\r\n * @memberof FlightGateFactory\r\n * @param {Array} objList an Array Of FlightGates\r\n * @returns {Array} FlightGates\r\n */\r\n\t\tfunction fromObjectList( objList ) {\r\n\t\t\tif (!objList)\r\n\t\t\t\treturn [];\r\n\r\n\t\t\tvar arrayLength = objList.length;\r\n\t\t\tvar result = [];\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tvar item = new FlightGate();\r\n\t\t\t\tangular.extend(item, objList[i]);\r\n\r\n\t\t\t\tresult.push(item);\r\n\t\t\t}\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('FlightInfoCtrl', FlightInfoCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FlightInfoCtrl\r\n * @description \r\n * Shows the flight informations\r\n * @ngInject\r\n */\r\n function FlightInfoCtrl($scope, FlightFactory, MessageFactory, $routeParams, AircaftPositionsFactory, CrewCallFactory, PreviousDutyFactory,\r\n $location, $uibModal, PaxInfoFactory, CampaignFactory, UserFactory, barOptions, $anchorScroll, enableFaceMasks,\r\n FlightCheckInsFactory, CrewRouteFactory) {\r\n\r\n var flightId = $routeParams.flightId;\r\n var flight = FlightFactory.getFlightFromTotalFlights(flightId);\r\n var crewPhoneNumbers = CrewCallFactory.getFlightCrewCallsFromStorage(flightId);\r\n var previousDuties = PreviousDutyFactory.getFlightPreviousDutiesFromStorage(flightId);\r\n \r\n $scope.user = UserFactory.getUser();\r\n $scope.flightId = flightId;\r\n $scope.shownSideMenu = false;\r\n $scope.sideMenuItems = [];\r\n $scope.showSidePanel = showSidePanel;\r\n $scope.hideSidePanel = hideSidePanel;\r\n $scope.goToPanel = goToPanel;\r\n\r\n $scope.isMobile = (window.innerWidth <= 800 && window.innerHeight <= 740);\r\n \r\n $scope.campaigns = CampaignFactory.getCampaignsByFlightId(+flightId); \r\n \r\n // function detectMobile() {\r\n // $scope.isMobile =(window.innerWidth <= 800 && window.innerHeight <= 740); \r\n // console.log($scope.isMobile);\r\n // return $scope.isMobile;\t\t\r\n // }\t\r\n\r\n function hideSidePanel() {\r\n $scope.shownSideMenu = false;\r\n }\r\n\r\n function goToPanel(id) {\r\n $location.hash(id);\r\n $anchorScroll();\r\n hideSidePanel();\r\n };\r\n\r\n function showSidePanel() {\r\n $scope.sideMenuItems = [];\r\n $('.panel-heading .title').each(function () {\r\n var menuItem = {};\r\n menuItem.id = $(this).attr(\"id\");\r\n menuItem.title = $(this).html();\r\n menuItem.icon = $(this).data('icon');\r\n $scope.sideMenuItems.push(menuItem);\r\n })\r\n $scope.shownSideMenu = true;\r\n }\r\n\r\n\r\n if (!flight) {\r\n // go to dashboard if no flight\r\n $location.path(\"/\");\r\n } else {\r\n\r\n applyPhoneNumber();\r\n applyPreviousDuty();\r\n applyCrewCheckInStatus();\r\n PaxInfoFactory.setMaskPaxInfoInRoute(flight);\r\n\r\n $scope.flightCrewPreviousDuty = flight.crew.filter(x => x.PreviousDuty && x.PreviousDuty.isDifferent && (x.position == \"CP\" || x.position == \"FO\") && !x.isDHC).length;\r\n $scope.cabinCrewPreviousDuty = flight.crew.filter(x => x.PreviousDuty && x.PreviousDuty.isDifferent && (x.position == \"SA\" || x.position == \"FA\") && !x.isDHC).length;\r\n $scope.dhcCrewPreviousDuty = flight.crew.filter(x => x.PreviousDuty && x.PreviousDuty.isDifferent && x.isDHC).length;\r\n $scope.hasPreviousDuties = $scope.flightCrewPreviousDuty + $scope.cabinCrewPreviousDuty + $scope.dhcCrewPreviousDuty;\r\n\r\n //Update scopes for the CrewRoutePanel in Flight-page\r\n $scope.crewRouteInfoPanel = CrewRouteFactory.getCrewRouteInfoPanel(flight);\r\n\r\n $scope.saEligibility = flight.LineStatus != 'na';\r\n // (flight.Position == \"SA\" || (flight.Position != \"SA\" && !flight.getSeniorAttendantsCount() && flight.Fleet.Id==2 ));\r\n\r\n //Manage Face Mask Panel visibility - Show only to SA or OA flights with no SA\r\n $scope.enableFaceMasks = enableFaceMasks && \r\n flight && \r\n $scope.saEligibility;\r\n\r\n //todo :: epap replace with flightId 1312896\r\n\r\n var aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId(flight.FlightId);\r\n\r\n $scope.state = 'flight'\r\n $scope.flight = flight;\r\n $scope.aircaftPositions = aircaftPositions;\r\n $scope.IsProvisional = true;\r\n $scope.flightZones = RenderFlightZones(flight.Zones);\r\n //Initialize Zones\r\n function onlyUnique(value, index, self) {\r\n return self.indexOf(value) === index;\r\n }\r\n function RenderFlightZones(zones) {\r\n\r\n if (!zones)\r\n return;\r\n\r\n var flightZones = [];\r\n\r\n var zoneTitles = zones.map(function (item) {\r\n return item.Title;\r\n });\r\n var uniqueZones = zoneTitles.filter(onlyUnique);\r\n // //or\r\n // var uniqueZones2 = Array.from(new Set(zoneTitles));\r\n\r\n uniqueZones.forEach(function (element) {\r\n\r\n var getZoneCounter = zoneTitles.filter(function (item) {\r\n return item == element;\r\n });\r\n if (getZoneCounter.length > 1) {\r\n flightZones.push({ Title: element.Title, Class: null })\r\n } else {\r\n var zone = zones.filter(function (item) {\r\n return item.Title == element;\r\n });\r\n flightZones.push(zone[0]);\r\n }\r\n });\r\n return flightZones;\r\n }\r\n\r\n //Initialize Messages\r\n $scope.messages = MessageFactory.getMessagesFromIds(flight.messages);\r\n var messages = $scope.messages;\r\n $scope.openMessage = openMessage;\r\n\r\n //Initialize scope variables\r\n $scope.isEnabled = false;\r\n $scope.isPanelOpen = true;\r\n $scope.showConnFlights = true;\r\n\r\n //Charts\r\n $scope.crewChart = generateCrewChart(flight);\r\n $scope.generateMealChart = generateMealChart;\r\n\r\n //1226541\r\n PaxInfoFactory.getPaxInfoFromStorage(flight.FlightId, function (paxInfo) {\r\n $scope.paxInfo = paxInfo;\r\n\r\n if (paxInfo) {\r\n\r\n $scope.cStat = (paxInfo.PaxTotalC / paxInfo.ConfigurationC) * 100;\r\n $scope.yStat = (paxInfo.PaxTotalY / paxInfo.ConfigurationY) * 100;\r\n\r\n $scope.mealsChart = generateMealChart(paxInfo);\r\n\r\n var listSentTimestamp = new Date(paxInfo.LastRun).getTime();\r\n var DepartureTimestamp = new Date(flight.ScheduledDeparture).getTime();\r\n //20 minutes before takeoff\r\n if (DepartureTimestamp - listSentTimestamp <= 1200000) {\r\n $scope.IsProvisional = false;\r\n }\r\n }\r\n });\r\n\r\n var flightArrivalTime = new Date(flight.ScheduledArrival).getTime();\r\n $scope.flightETA = flight.ETA ? new Date(flight.ETA).getTime() : flightArrivalTime;\r\n\r\n //Initialize scope functionality\r\n $scope.IsOld = IsOld;\r\n $scope.isConnectedFlightClose = isConnectedFlightClose;\r\n $scope.TimeDifference = TimeDifference;\r\n $scope.openFlightConfig = openFlightConfig;\r\n $scope.openGates = openGates;\r\n\r\n //TODO : find a more angular way (EPAP)\r\n\r\n $scope.togglePanel = togglePanel;\r\n //TODO : find a more angular way (EPAP)\r\n $scope.toggleViewMode = toggleViewMode;\r\n\r\n\r\n //Initialize CSS classes\r\n $scope.getTextClass = getTextClass();\r\n $scope.getTopClass = getTopClass();\r\n $scope.getBottomClass = getBottomClass();\r\n $scope.hasIcon = hasIcon();\r\n $scope.getAssessmentTextClass = getAssessmentTextClass();\r\n\r\n //Controllers Functions\r\n\r\n //TODO : find a more angular way (EPAP)\r\n /**\r\n * toggle View Mode\r\n * @memberof FlightInfoCtrl\r\n * @param {string} elem\r\n * @param {string} className \r\n */\r\n function toggleViewMode(elem, className) {\r\n $('body').find('div#' + elem + ' > div').not('.tip').hide(\"slow\");\r\n $('body').find('div#' + elem + ' div.' + className).not('.tip').show(\"slow\");\r\n }\r\n\r\n //TODO : find a more angular way (EPAP)\r\n /**\r\n * toggle Panel\r\n * @memberof FlightInfoCtrl\r\n * @param {number} panelId\r\n */\r\n function togglePanel(panelId) {\r\n $('#' + panelId).toggle();\r\n if (panelId == \"info-panel\")\r\n $scope.isPanelOpen = !$scope.isPanelOpen;\r\n }\r\n\r\n\r\n\r\n /**\r\n * Open modal to see information for the selected message\r\n * @memberof FlightInfoCtrl\r\n * @param {object} message A message object\r\n */\r\n function openMessage(message) {\r\n\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgMessage.html',\r\n controller: 'MessageModalCtrl',\r\n size: 'lg',\r\n keyboard: false,\r\n backdrop: \"static\",\r\n resolve: {\r\n message: function () {\r\n return message;\r\n }\r\n }\r\n });\r\n\r\n modalInstance.result.then(function () {\r\n if (message.ReadDt == null) {\r\n MessageFactory.markReaden(message.Id);\r\n message.ReadDt = new Date();\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * Open modal to see information for gates and connections\r\n * @memberof FlightInfoCtrl\r\n */\r\n function openGates() {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgFlightGates.html',\r\n controller: 'FlightGateCtrl',\r\n size: 'lg',\r\n resolve: {\r\n flight: function () {\r\n return $scope.flight;\r\n }\r\n }\r\n });\r\n modalInstance.result.then(function (selectedItem) {\r\n $scope.gates = selectedItem;\r\n });\r\n }\r\n\r\n\r\n /**\r\n * Return the text ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\r\n function getTextClass() {\r\n var classname = \"\";\r\n if (flight.LineStatus === 'na')\r\n classname = \"text-gray\";\r\n else if (flight.LineStatus === 'pending')\r\n classname = \"text-blue\";\r\n else if (flight.LineStatus === 'pendingoverdue')\r\n classname = \"text-blue\";\r\n else if (\r\n (flight.LineStatus === 'draft') ||\r\n (flight.LineStatus === 'draftotheruser')\r\n ) {\r\n classname = \"text-orange\";\r\n } else if (\r\n (flight.LineStatus === 'completed') ||\r\n (flight.LineStatus === 'completedotheruser')\r\n ) {\r\n classname = \"text-purple\";\r\n } else if (\r\n (flight.LineStatus === 'stored') ||\r\n (flight.LineStatus === 'storedotheruser') ||\r\n (flight.LineStatus === 'stored+otheruser') ||\r\n (flight.LineStatus === 'synched') ||\r\n (flight.LineStatus === 'synchedotheruser')\r\n ) {\r\n classname = \"text-green\";\r\n }\r\n return classname;\r\n }\r\n\r\n /**\r\n * Return the panel upper ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\r\n function getTopClass() {\r\n var classname = \"\";\r\n if (flight.LineStatus === 'na')\r\n classname = \"border-top-gray\";\r\n else if (flight.LineStatus === 'pending')\r\n classname = \"border-top-blue\";\r\n else if (flight.LineStatus === 'pendingoverdue')\r\n classname = \"border-top-blue\";\r\n else if (\r\n (flight.LineStatus === 'draft') ||\r\n (flight.LineStatus === 'draftotheruser')\r\n ) {\r\n classname = \"border-top-orange\";\r\n } else if (\r\n (flight.LineStatus === 'completed') ||\r\n (flight.LineStatus === 'completedotheruser')\r\n ) {\r\n classname = \"border-top-purple\";\r\n } else if (\r\n (flight.LineStatus === 'stored') ||\r\n (flight.LineStatus === 'storedotheruser') ||\r\n (flight.LineStatus === 'stored+otheruser') ||\r\n (flight.LineStatus === 'synched') ||\r\n (flight.LineStatus === 'synchedotheruser')\r\n ) {\r\n classname = \"border-top-green\";\r\n }\r\n return classname;\r\n }\r\n\r\n /**\r\n * Return the panel border ccs class accoriding to report status\r\n * @memberof FlightInfoCtrl\r\n * @returns {string} cssClass\r\n */\r\n function getBottomClass() {\r\n var classname = \"\";\r\n if (flight.LineStatus === 'na')\r\n classname = \"border-bottom-gray\";\r\n else if (flight.LineStatus === 'pending')\r\n classname = \"border-bottom-blue\";\r\n else if (flight.LineStatus === 'pendingoverdue')\r\n classname = \"border-bottom-blue\";\r\n else if (\r\n (flight.LineStatus === 'draft') ||\r\n (flight.LineStatus === 'draftotheruser')\r\n ) {\r\n classname = \"border-bottom-orange\";\r\n } else if (\r\n (flight.LineStatus === 'completed') ||\r\n (flight.LineStatus === 'completedotheruser')\r\n ) {\r\n classname = \"border-bottom-purple\";\r\n } else if (\r\n (flight.LineStatus === 'stored') ||\r\n (flight.LineStatus === 'storedotheruser') ||\r\n (flight.LineStatus === 'stored+otheruser') ||\r\n (flight.LineStatus === 'synched') ||\r\n (flight.LineStatus === 'synchedotheruser')\r\n ) {\r\n classname = \"border-bottom-green\";\r\n }\r\n return classname;\r\n }\r\n\r\n /**\r\n * If report from another user exists, show icon\r\n * @memberof FlightInfoCtrl\r\n * @returns {boolean} hasIcon\r\n */\r\n function hasIcon() {\r\n var hasIcon = false;\r\n if (\r\n (flight.LineStatus === 'draftotheruser') ||\r\n (flight.LineStatus === 'completedotheruser') ||\r\n (flight.LineStatus === 'storedotheruser') ||\r\n (flight.LineStatus === 'stored+otheruser') ||\r\n (flight.LineStatus === 'synchedotheruser')\r\n ) {\r\n hasIcon = true;\r\n }\r\n return hasIcon;\r\n }\r\n\r\n /**\r\n * Checks if the data are new\r\n * @memberof FlightInfoCtrl\r\n * @param {string} time timestamp\r\n * @return {boolean} IsOld\r\n */\r\n function IsOld(time) {\r\n IsOld = false;\r\n if (time) {\r\n var now = new Date();\r\n var timeDate = new Date(time);\r\n var diff = now.getTime() - timeDate.getTime();\r\n if (diff > 3600000) {\r\n IsOld = true;\r\n }\r\n }\r\n return IsOld;\r\n }\r\n\r\n /**\r\n * Calculates if a connecting flight is departs sort time after fligths arrival \r\n * @memberof FlightInfoCtrl\r\n * @param {string} connection Connection STD\r\n * @return {string} cssClass\r\n */\r\n function isConnectedFlightClose(connection) {\r\n if (!connection) {\r\n return '';\r\n }\r\n\r\n var connFlightDate = new Date(connection.STD).getTime();\r\n\r\n if ($scope.flightETA > connFlightDate)\r\n return '';\r\n\r\n if ((connFlightDate - $scope.flightETA) < connection.MCT * 60000) {\r\n return 'bg-bisque';\r\n }\r\n\r\n if ((connFlightDate - $scope.flightETA) < (connection.MCT + 15) * 60000) {\r\n return 'bg-cornsilk';\r\n }\r\n return '';\r\n }\r\n\r\n\r\n /**\r\n * Returns the time difference\r\n * @memberof FlightInfoCtrl\r\n * @param {string} time Connection STD\r\n * @return {string} timeDifference\r\n */\r\n function TimeDifference(time) {\r\n var timeString = '';\r\n var sign = '';\r\n var dayString = null;\r\n\r\n if (time) {\r\n var connFlightDate = new Date(time);\r\n var ms = connFlightDate.getTime() - $scope.flightETA; // this is a time in milliseconds\r\n if (ms < 0) {\r\n ms = -ms;\r\n sign = \"-\";\r\n }\r\n var days = Math.floor(ms / (24 * 60 * 60 * 1000));\r\n days = days < 0 ? days + 1 : days;\r\n var daysms = ms % (24 * 60 * 60 * 1000);\r\n var hours = Math.floor((daysms) / (60 * 60 * 1000));\r\n var hoursms = ms % (60 * 60 * 1000);\r\n var minutes = Math.floor((hoursms) / (60 * 1000));\r\n timeString = '' + sign + (hours > 0 ? (\"0\" + hours).substr(-2) + \":\" : '') + (\"0\" + minutes).substr(-2) + '\\'' + '';\r\n dayString = ' ' + days + 'd';\r\n }\r\n\r\n return timeString + ((days && days != 0) ? dayString : '');\r\n }\r\n\r\n /**\r\n * Open Flight config modal\r\n * @memberof FlightInfoCtrl\r\n */\r\n function openFlightConfig() {\r\n\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgFlightConfig.html',\r\n controller: 'FlightConfigCtrl',\r\n size: 'md',\r\n resolve: {\r\n flight: function () {\r\n return $scope.flight;\r\n }\r\n }\r\n });\r\n\r\n modalInstance.result.then(function (selectedItem) {\r\n $scope.flightETA = new Date(selectedItem.ETA).getTime();\r\n $scope.flight = selectedItem;\r\n });\r\n }\r\n\r\n /**\r\n * Returns the assessment Text Class\r\n * @memberof FlightInfoCtrl\r\n * @return {string} classname\r\n */\r\n function getAssessmentTextClass() {\r\n var classname = \"\";\r\n if (flight.assessment) {\r\n if (flight.assessment.IsExist) {\r\n classname = \"text-green\";\r\n } else if (flight.assessment.Status === 'Pending')\r\n classname = \"text-blue\";\r\n else if (flight.assessment.Status === 'Draft') {\r\n classname = \"text-orange\";\r\n } else if (flight.assessment.Status === 'Completed') {\r\n classname = \"text-purple\";\r\n } else if (flight.assessment.Status === 'Stored') {\r\n classname = \"text-green\";\r\n }\r\n }\r\n return classname;\r\n }\r\n\r\n /**\r\n * Returns the crew Chart\r\n * @memberof FlightInfoCtrl\r\n * @param {object} flight The flight object\r\n * @return {object} crewChart\r\n */\r\n function generateCrewChart(flight) {\r\n\r\n var cp = 0;\r\n var fo = 0;\r\n var sa = 0;\r\n var fa = 0;\r\n\r\n var dhcCp = 0;\r\n var dhcFo = 0;\r\n var dhcSa = 0;\r\n var dhcFa = 0;\r\n\r\n if (flight.crew) {\r\n for (var i = 0; i < flight.crew.length; i++) {\r\n if (flight.crew[i].isDHC) {\r\n switch (flight.crew[i].position) {\r\n case \"CP\":\r\n dhcCp++;\r\n break;\r\n case \"FO\":\r\n dhcFo++;\r\n break;\r\n case \"SA\":\r\n dhcSa++;\r\n break;\r\n case \"FA\":\r\n dhcFa++;\r\n break;\r\n }\r\n } else {\r\n switch (flight.crew[i].position) {\r\n case \"CP\":\r\n cp++;\r\n break;\r\n case \"FO\":\r\n fo++;\r\n break;\r\n case \"SA\":\r\n sa++;\r\n break;\r\n case \"FA\":\r\n fa++;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n var crewData = {\r\n labels: [\"CP\", \"FO\", \"SA\", \"FA\"],\r\n datasets: [{\r\n label: \"Crew\",\r\n fillColor: \"rgba(33,150,243,0.5)\",\r\n strokeColor: \"rgba(33,150,243,0.8)\",\r\n highlightFill: \"rgba(33,150,243,0.75)\",\r\n highlightStroke: \"rgba(33,150,243,1)\",\r\n data: [cp, fo, sa, fa]\r\n }, {\r\n label: \"DHC\",\r\n fillColor: \"rgba(99,181,246,0.5)\",\r\n strokeColor: \"rgba(99,181,246,0.8)\",\r\n highlightFill: \"rgba(99,181,246,0.75)\",\r\n highlightStroke: \"rgba(99,181,246,1)\",\r\n data: [dhcCp, dhcFo, dhcSa, dhcFa]\r\n }]\r\n };\r\n\r\n var crewChart = {\r\n \"data\": crewData,\r\n \"options\": barOptions\r\n };\r\n\r\n return crewChart;\r\n }\r\n\r\n /**\r\n * Returns the meal Chart\r\n * @memberof FlightInfoCtrl\r\n * @param {object} paxInfo The passenger list\r\n * @return {object} mealChart\r\n */\r\n function generateMealChart(paxInfo) {\r\n var labels = [];\r\n var mealCdata = [];\r\n var mealYdata = [];\r\n\r\n for (var i = 0; i < paxInfo.PassengerSummaryC.SpecialMeals.length; i++) {\r\n labels.push(paxInfo.PassengerSummaryC.SpecialMeals[i].Name);\r\n mealCdata.push(paxInfo.PassengerSummaryC.SpecialMeals[i].Count);\r\n mealYdata.push(0);\r\n }\r\n\r\n for (var i = 0; i < paxInfo.PassengerSummaryY.SpecialMeals.length; i++) {\r\n var exists = false;\r\n for (var h = 0; h < labels.length; h++) {\r\n if (labels[h] == paxInfo.PassengerSummaryY.SpecialMeals[i].Name) {\r\n mealYdata[h] = paxInfo.PassengerSummaryY.SpecialMeals[i].Count\r\n exists = true;\r\n break;\r\n }\r\n }\r\n if (!exists) {\r\n labels.push(paxInfo.PassengerSummaryY.SpecialMeals[i].Name);\r\n mealCdata.push(paxInfo.PassengerSummaryY.SpecialMeals[i].Count);\r\n mealYdata.push(0);\r\n }\r\n }\r\n\r\n var mealsData = {\r\n labels: labels,\r\n datasets: [{\r\n label: \"Business\",\r\n fillColor: \"rgba(139,195,74,0.5)\",\r\n strokeColor: \"rgba(139,195,74,0.8)\",\r\n highlightFill: \"rgba(139,195,74,0.75)\",\r\n highlightStroke: \"rgba(139,195,74,1)\",\r\n data: mealCdata\r\n }, {\r\n label: \"Economy\",\r\n fillColor: \"rgba(173,213,128,0.5)\",\r\n strokeColor: \"rgba(173,213,128,0.8)\",\r\n highlightFill: \"rgba(173,213,128,0.75)\",\r\n highlightStroke: \"rgba(173,213,128,1)\",\r\n data: mealYdata\r\n }]\r\n };\r\n\r\n var mealsChartData = {\r\n \"data\": mealsData,\r\n \"options\": barOptions\r\n };\r\n\r\n return mealsChartData;\r\n }\r\n\r\n /**\r\n * Returns the meal Chart\r\n * @memberof FlightInfoCtrl\r\n * @param {array} gates The total available gates\r\n * @param {array} FlightsFilters The flilters for the gates\r\n * @return {array} distinct_gates\r\n */\r\n function generateDistinctGates(gates, FlightsFilters) {\r\n var distinct_gates = [];\r\n\r\n for (var i = 0; i < gates.length; i++) {\r\n for (var j = 0; j < FlightsFilters.length; j++) {\r\n var row = gates[i].FlightNo + \",\" + gates[i].Codeshares.toString();\r\n if (row.indexOf(FlightsFilters[j].toString()) >= 0) {\r\n var distinct_gate = {\r\n FlightNo: gates[i].FlightNo,\r\n Gate: gates[i].DepGate,\r\n Arr: gates[i].Arrival,\r\n STD_lcl: gates[i].STD_lcl,\r\n STD: gates[i].STD,\r\n pax: null,\r\n Codeshares: gates[i].Codeshares\r\n }\r\n distinct_gates.push(distinct_gate);\r\n break;\r\n }\r\n }\r\n }\r\n\r\n return distinct_gates;\r\n }\r\n \r\n\r\n function applyPhoneNumber(){\r\n flight.crew.forEach(function(user){\r\n var phoneNumberInfo = crewPhoneNumbers.find(x => x.CrewId == user.id);\r\n if(phoneNumberInfo){\r\n user.PhoneNumber = phoneNumberInfo.PhoneNumber;\r\n }\r\n else{\r\n user.PhoneNumber = null;\r\n }\r\n });\r\n }\r\n \r\n function applyPreviousDuty(){\r\n var dutyDate = moment(flight.ScheduledDeparture).startOf('day');\r\n\r\n flight.crew.forEach(function(user){\r\n\r\n var previousDutyInfo = previousDuties.find(x => x.CrewId == user.id);\r\n if(previousDutyInfo){\r\n user.PreviousDuty = previousDutyInfo.PreviousDuty;\r\n }\r\n else{\r\n user.PreviousDuty = null;\r\n }\r\n\r\n if(user.PreviousDuty && user.PreviousDuty.isFlight){\r\n var arrivalDate = user.PreviousDuty.ATA;\r\n if(!arrivalDate) arrivalDate = user.PreviousDuty.ETA;\r\n if(!arrivalDate) arrivalDate = user.PreviousDuty.STA;\r\n\r\n user.PreviousDuty.showArrivalDate = !moment(arrivalDate).startOf('day').isSame(dutyDate);\r\n\r\n var departureDate = user.PreviousDuty.ATA;\r\n if(!departureDate) departureDate = user.PreviousDuty.ETA;\r\n if(!departureDate) departureDate = user.PreviousDuty.STA;\r\n\r\n user.PreviousDuty.showDepartureDate = !moment(departureDate).startOf('day').isSame(dutyDate);\r\n\r\n }\r\n if(user.PreviousDuty && !user.PreviousDuty.isFlight){\r\n user.PreviousDuty.showDate = !moment(user.PreviousDuty.GroundDutyDate).startOf('day').isSame(dutyDate);\r\n }\r\n });\r\n }\r\n\r\n function applyCrewCheckInStatus(){\r\n var crewCheckInStatuses = FlightCheckInsFactory.getFlightCrewCheckInFromStorage(flightId);\r\n flight.crew.forEach(function(user){\r\n var statuses = crewCheckInStatuses.find(x => x.CrewId == user.id);\r\n if(statuses){\r\n user.CheckIn = statuses.CheckIn;\r\n user.WillBeThereAt = statuses.WillBeThereAt;\r\n }\r\n else{\r\n user.CheckIn = null;\r\n user.WillBeThereAt = null;\r\n }\r\n });\r\n }\r\n \r\n }\r\n }\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('flightStatus',flightStatus);\r\n\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name flightStatus\r\n * @restrict EA\r\n * @description\r\n * Implementation of flightStatus\r\n *\r\n * Initialize the flight Status panel needs to have flight in scope\r\n * @example\r\n * Usage:\r\n *
\r\n * @ngInject\r\n */ \r\nfunction flightStatus(AircaftPositionsFactory) {\r\n \r\n function link ($scope, element, attrs) {\r\n $scope.securitySearch = false;\r\n\r\n $scope.previousActualTAT = null;\r\n $scope.previousEstimatedTAT = null;\r\n $scope.previousScheduledTAT = null;\r\n $scope.previousDiffWithSceduled = null;\r\n\r\n $scope.nextActualTAT = null;\r\n $scope.nextEstimatedTAT = null;\r\n $scope.nextScheduledTAT = null;\r\n $scope.nextDiffWithSceduled = null;\r\n\r\n\r\n if($scope.flight && $scope.flight.FlightId){\r\n $scope.aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId($scope.flight.FlightId);\r\n }\r\n\r\n if($scope.aircaftPositions != null){\r\n //TurnAroundTime();\r\n }\r\n \r\n\r\n function TurnAroundTime(){\r\n\r\n var previousTemporaryActualValue;\r\n var nextTemporaryActualValue;\r\n \r\n //TurnAroundTime for previous flight\r\n if($scope.aircaftPositions.PreviousATA && $scope.flight.ATD){\r\n previousTemporaryActualValue = Date.DifferenceInMinutes($scope.aircaftPositions.PreviousATA, $scope.flight.ATD);\r\n $scope.previousActualTAT = normalizeMins(previousTemporaryActualValue);\r\n }\r\n else if($scope.aircaftPositions.PreviousETA && $scope.flight.ETD){\r\n previousTemporaryActualValue = Date.DifferenceInMinutes($scope.aircaftPositions.PreviousETA, $scope.flight.ETD);\r\n $scope.previousEstimatedTAT = normalizeMins(previousTemporaryActualValue);\r\n }\r\n if($scope.aircaftPositions.PreviousSTA && $scope.flight.ScheduledDeparture){\r\n var previousTemporaryScheduledValue = Date.DifferenceInMinutes($scope.aircaftPositions.PreviousSTA, $scope.flight.ScheduledDeparture);\r\n $scope.previousScheduledTAT = normalizeMins(previousTemporaryScheduledValue);\r\n var tempDiff = previousTemporaryActualValue - previousTemporaryScheduledValue;\r\n //difference (mins) between Actual and Scheduled\r\n if(tempDiff>= -70 && tempDiff <= 70 )\r\n $scope.previousDiffWithSceduled = normalizeMins(tempDiff, true);\r\n }\r\n\r\n //TurnAroundTime for next flight\r\n if($scope.flight.ATA && $scope.aircaftPositions.NextATD){\r\n nextTemporaryActualValue = Date.DifferenceInMinutes($scope.aircaftPositions.flight.ATA, $scope.aircaftPositions.NextATD);\r\n $scope.nextActualTAT = normalizeMins(nextTemporaryActualValue);\r\n }\r\n else if($scope.flight.ETA && $scope.aircaftPositions.NextETD){\r\n nextTemporaryActualValue = Date.DifferenceInMinutes($scope.aircaftPositions.flight.ETA, $scope.aircaftPositions.NextETD);\r\n $scope.nextEstimatedTAT = normalizeMins(nextTemporaryActualValue);\r\n }\r\n if($scope.flight.ScheduledArrival && $scope.aircaftPositions.NextSTD){\r\n var nextTemporaryScheduledValue = Date.DifferenceInMinutes($scope.aircaftPositions.ScheduledArrival, $scope.aircaftPositions.NextSTD);\r\n $scope.nextScheduledTAT = normalizeMins(nextTemporaryScheduledValue);\r\n var tempDiff = nextTemporaryActualValue - nextTemporaryScheduledValue;\r\n //difference (mins) between Actual and Scheduled\r\n if(tempDiff>= -70 && tempDiff <= 70 )\r\n $scope.nextDiffWithSceduled = normalizeMins(tempDiff, true);\r\n }\r\n\r\n }\r\n\r\n function normalizeMins(diffInMins, canBeNegativeNumber){\r\n var returnString = \"\";\r\n //negative value - return mins\r\n if(canBeNegativeNumber && diffInMins < 0 ){\r\n returnString = diffInMins * -1 + \"mins less than scheduled\";\r\n }\r\n //positive value - return mins\r\n else if(canBeNegativeNumber)\r\n {\r\n returnString = diffInMins + \"mins more than scheduled\"\r\n }\r\n //positive value - return hours like \"2hrs 30mins\"\r\n else{\r\n returnString = Date.MinutesToString(diffInMins);\r\n }\r\n\r\n return returnString;\r\n }\r\n function needsSecuritySearch(){\r\n \r\n if($scope.aircaftPositions.PreviousEU){\r\n $scope.securitySearch = false;\r\n }\r\n \r\n if($scope.aircaftPositions.PreviousCounty == \"SWITZERLAND\" \r\n ||$scope.aircaftPositions.PreviousCounty == \"NORWAY\"\r\n ||$scope.aircaftPositions.PreviousCounty == \"ICELAND\"\r\n ||$scope.aircaftPositions.PreviousCounty == \"MONTENEGRO\"){\r\n $scope.securitySearch = false;\r\n }\r\n \r\n if($scope.aircaftPositions.PreviousCounty == \"UNITED KINGDOM\" \r\n ||$scope.aircaftPositions.PreviousCounty == \"FRANCE\"){\r\n $scope.securitySearch = true;\r\n }\r\n \r\n if($scope.flight.ArrivalCountry == \"TURKEY\" \r\n ||$scope.flight.ArrivalCountry == \"EGYPT\"\r\n ||$scope.flight.ArrivalCountry == \"ISRAEL\"\r\n ||$scope.flight.ArrivalCountry == \"JORDAN\"\r\n ||$scope.flight.ArrivalCountry == \"SAUDI ARABIA\"){\r\n $scope.securitySearch = true;\r\n }\r\n \r\n }\r\n\r\n }\r\n return {\r\n\t\t\trestrict: 'EA',\r\n\t\t\tterminal: true,\r\n templateUrl: 'views/directives/flightStatus.tpl.html',\r\n\t\t\tscope : false,\r\n link: link \r\n }\r\n}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('GroundServicesFactory', GroundServicesFactory);\r\n /**\r\n * @memberOf CabinReports\r\n * @ngdoc factory\r\n * @name GroundServicesFactory\r\n * @description\r\n * Get Ground Services\r\n * @gnInject\r\n */\r\n\r\n function GroundServicesFactory(GenericService) {\r\n /**\r\n * Initialize the GroundServices\r\n * @memberof GroundServicesFactory\r\n */\r\n function GroundService() {\r\n this.Station = null;\r\n }\r\n\r\n var objType = 'groundServices';\r\n var objCallBack = GroundService;\r\n\r\n var service = {\r\n fromObjectList: fromObjectList,\r\n getGroundServicesFromStorage: getGroundServicesFromStorage,\r\n setGroundServicesToStorage: setGroundServicesToStorage,\r\n clearGroundServicesFromStorage: clearGroundServicesFromStorage,\r\n getGroundServicesByStation: getGroundServicesByStation,\r\n upsertGroundServices : upsertGroundServices\r\n };\r\n\r\n /**\r\n * Extend an array of Objects from the default GroundService Object\r\n * @memberof GroundServicesFactory\r\n * @param {Array} objList an Array Of ground Services\r\n * @returns {Array} groundServices\r\n */\r\n function fromObjectList(objList) {\r\n return GenericService.fromObjectList(objList, objCallBack);\r\n }\r\n /**\r\n * Get ground services from local storage\r\n * @memberof GroundServicesFactory\r\n * @returns {Array} groundServices \r\n */\r\n function getGroundServicesFromStorage() {\r\n return GenericService.list(objType, objCallBack);\r\n }\r\n\r\n /**\r\n * Save ground services to storage\r\n * @memberof GroundServicesFactory\r\n * @param {Array} List of ground services\r\n */\r\n function setGroundServicesToStorage(groundServices) {\r\n for (var i = 0; i < groundServices.length; i++) {\r\n for (var j = 0; j < groundServices[i].Services.length; j++){\r\n // isDefault could be null\r\n if (groundServices[i].Services[j].IsDefault)\r\n groundServices[i].Services[j].Used = 1;\r\n else\r\n groundServices[i].Services[j].Used = 0;\r\n }\r\n }\r\n GenericService.saveAll(groundServices, objType, objCallBack);\r\n }\r\n\r\n /**\r\n * Remove the ground services from the local storage\r\n * @memberof GroundServicesFactory\r\n */\r\n function clearGroundServicesFromStorage() {\r\n GenericService.removeAll(objType, objCallBack);\r\n }\r\n\r\n\r\n /**\r\n * Get Ground Services of a current station from the local storage\r\n * @memberof GroundServicesFactory\r\n * @param {number} station \r\n * @return {object} GroundServices \r\n */\r\n function getGroundServicesByStation(station) {\r\n \r\n var objects = getGroundServicesFromStorage();\r\n if (objects == null)\r\n return [];\r\n\r\n var results = [];\r\n\r\n var arrayLength = objects.length;\r\n for (var i = 0; i < arrayLength; i++) {\r\n if (objects[i].Station == station) {\r\n results = objects[i].Services;\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n /**\r\n * Upsert ground services\r\n * @memberof GroundServicesFactory\r\n */\r\n function upsertGroundServices(groundServices) {\r\n var newStations = groundServices.map(x => x.Station);\r\n var servicesLS = this.getGroundServicesFromStorage();\r\n servicesLS = servicesLS.filter(x => !newStations.includes(x.Station));\r\n var updatedServicesList = servicesLS.concat(groundServices);\r\n setGroundServicesToStorage(updatedServicesList);\r\n }\r\n\r\n return service;\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('passengerEvents', passengerEvents);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name passengerEvents\r\n * @restrict E\r\n * @description\r\n * Implementation of passengerEvents\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function passengerEvents(ToolkitFactory, CustomerEventFactory) {\r\n function link(scope) {\r\n \r\n var Passengers = [];\r\n\r\n //Get all OneStopShop customer events of this flight\r\n var customerEvents = CustomerEventFactory.groupFlightCustomerEventsByPassenger(scope.flightId);\r\n\r\n ToolkitFactory.getToolkitItemsFromStorage(function(toolKitItems){\r\n //Merge each event with its toolkit Item\r\n customerEvents.forEach(function(customerEvent){\r\n customerEvent.OneStopShopEvents.forEach(function(event){\r\n event.ToolkitItem = toolKitItems.find(x => x.Id == event.ToolkitItemId);\r\n event.Treatment = toolKitItems.find(x => x.Id == event.ToolkitItemId).Treatments.find(t => t.Id == event.TreatmentId);\r\n });\r\n });\r\n\r\n // OneStopShopEvent Passengers\r\n customerEvents.forEach(function(customerEvent){\r\n //Passenger already exists - Only add events\r\n if(Passengers.map(p => p.UCI).includes(customerEvent.UCI)){\r\n Passengers.find(p => p.UCI == customerEvent.UCI).OneStopShopEvents = customerEvent.OneStopShopEvents;\r\n }\r\n //Add Passenger Info & Events\r\n else{\r\n var passenger = {\r\n UCI: customerEvent.UCI,\r\n GivenName: customerEvent.GivenName,\r\n Surname: customerEvent.Surname,\r\n SeatNo: customerEvent.SeatNo,\r\n OneStopShopEvents : customerEvent.OneStopShopEvents,\r\n numberOfEvents: customerEvent.OneStopShopEvents.length,\r\n isOpen: false\r\n };\r\n\r\n Passengers.push(passenger);\r\n }\r\n });\r\n\r\n scope.Passengers = Passengers;\r\n });\r\n \r\n }\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/Flight/passengerEvents.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.filter('paxNames', paxNames);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc filter\r\n * @name paxNames\r\n * @description \r\n * List pax names in list and return $sce html \r\n * @ngInject\r\n */ \r\nfunction paxNames($sce) {\r\n return function(input) {\r\n var html = '\"
C
Y
';\r\n \r\n html = html + \"
Passengers \"\r\n html = html + '
' + input.PassengerSummaryC.Passengers + \"
\";\r\n html = html + '
' + input.PassengerSummaryY.Passengers + '
';\r\n\r\n html = html + \"
PRM \"\r\n html = html + '
' + input.PassengerSummaryC.PRM + \"
\";\r\n html = html + '
' + input.PassengerSummaryY.PRM + '
';\r\n\r\n html = html + \"
UMNR \"\r\n html = html + '
' + input.PassengerSummaryC.UMNR + \"
\";\r\n html = html + '
' + input.PassengerSummaryY.UMNR + '
';\r\n\r\n html = html + \"
DEP \"\r\n html = html + '
' + input.PassengerSummaryC.DEP + \"
\";\r\n html = html + '
' + input.PassengerSummaryY.DEP + '
\\\"';\r\n \r\n \r\n return $sce.trustAsHtml(html);\r\n }\r\n};\r\n\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.controller('SyncPaxCtrl', SyncPaxCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SyncPaxCtrl\r\n * @description \r\n * Get the latest PAX and gate Information\r\n * @ngInject\r\n */\r\n\tfunction SyncPaxCtrl($scope, InfoAPIService, $uibModalInstance, $route, flightId, LogService, FlightFactory, FlightSessionFactory, CourseFactory, CrewCallFactory, PreviousDutyFactory) {\r\n\r\n\t\tvar flight = FlightFactory.getFlightFromTotalFlights(flightId);\r\n\r\n\t\t$scope.hideElements = true;\r\n\t\t$scope.showOnSuccess = false;\r\n\t\t$scope.showOnEmptyData = false;\r\n\t\t$scope.showOnSuccessNoFlightData = false;\r\n\t\t$scope.showOnOutOfDateRange = false;\r\n\t\t$scope.cancel = cancel;\r\n\t\t$scope.flightId = flightId;\r\n\r\n\t\t$scope.isFetchingFlightData = false;\r\n\t\t$scope.flightDataStatus = [\r\n\t\t\t{\r\n\t\t\t\tdatatype: \"Flight Status\",\r\n\t\t\t\tstatus: \"PENDING\",\r\n\t\t\t\ttext: \"Pending...\"\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\tdatatype: \"Aircraft Movement\",\r\n\t\t\t\tstatus: \"PENDING\",\r\n\t\t\t\ttext: \"Pending...\"\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\tdatatype: \"Crew Info\",\r\n\t\t\t\tstatus: \"PENDING\",\r\n\t\t\t\ttext: \"Pending...\"\r\n\t\t\t},\r\n\t\t\t{\r\n datatype: \"Crew Contacts\",\r\n status: \"PENDING\",\r\n text: \"Pending...\"\r\n },\r\n\t\t\t// {\r\n\t\t\t// \tdatatype: \"Aims Crew Memos\",\r\n\t\t\t// \tstatus: \"PENDING\",\r\n\t\t\t// \ttext: \"Pending...\"\r\n\t\t\t// },\r\n\t\t\t{\r\n\t\t\t\tdatatype: \"Pax Info\",\r\n\t\t\t\tstatus: \"PENDING\",\r\n\t\t\t\ttext: \"Pending...\"\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\tdatatype: \"Meals\",\r\n\t\t\t\tstatus: \"PENDING\",\r\n\t\t\t\ttext: \"Pending...\"\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\tdatatype: \"Connections\",\r\n\t\t\t\tstatus: \"PENDING\",\r\n\t\t\t\ttext: \"Pending...\"\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\tdatatype: \"Campaigns\",\r\n\t\t\t\tstatus: \"PENDING\",\r\n\t\t\t\ttext: \"Pending...\"\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\tdatatype: \"Luggage Info\",\r\n\t\t\t\tstatus: \"PENDING\",\r\n\t\t\t\ttext: \"Pending...\"\r\n\t\t\t},\r\n\t\t\t{\r\n\t\t\t\tdatatype: \"Training Info\",\r\n\t\t\t\tstatus: \"PENDING\",\r\n\t\t\t\ttext: \"Pending...\"\r\n\t\t\t}\r\n\t\t];\r\n\r\n\r\n\t\t$uibModalInstance.closed.then(function () {\r\n\t\t\t$route.reload();\r\n\t\t});\r\n\r\n\t\tvar isThisFlightSynced = false;\r\n\r\n\r\n /**\r\n * Close the modal\r\n * @memberof SyncPaxCtrl\r\n */\r\n\t\tfunction cancel() {\r\n\t\t\t$uibModalInstance.close('close');\r\n\t\t};\r\n\r\n\t\tvar q = InfoAPIService.getPax(flightId);\r\n\t\t$scope.isFetchingFlightData = true;\r\n\r\n\t\tq.then(function (responseData) {\r\n\t\t\tupdateStatusGenerator(responseData);\r\n\t\t\t$scope.isFetchingFlightData = !($scope.isFetchingFlightData);\r\n\r\n\r\n\t\t\tif (responseData == undefined || responseData.data == undefined || responseData.data.data == undefined) {\r\n\t\t\t\tvar err = new Error();\r\n\t\t\t\terr.status = -1;\r\n\t\t\t\tvar msg = \"ResponseData error in sync :\" + JSON.stringify(responseData);\r\n\t\t\t\tLogService.debug(msg, err)\r\n\t\t\t\tq.reject(err);\r\n\t\t\t}\r\n\r\n\t\t\t//Save training\r\n\t\t\tvar trainingCourses = responseData.data.data.TrainingCourses;\r\n\t\t\tif(trainingCourses && trainingCourses.length){\r\n\t\t\t\ttrainingCourses.forEach(function(trainingCourse){\r\n\t\t\t\t\tCourseFactory.upsertCourse(trainingCourse, function(course) {\r\n\t\t\t\t\t\tFlightSessionFactory.applyTraineeInfoToSession(course, course.Id, new moment(flight.DutyDate).format(\"YYYY-MM-DD\"), flight.DutyNo, flight.DutyDay, function(session) {\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\r\n\t\t\t//1. First remove all additional info (phone numbers & previous duties) for this flight\r\n\t\t\tCrewCallFactory.cleanFlightCrewNumbers(flightId);\r\n PreviousDutyFactory.cleanFlightPreviousDuties(flightId);\r\n\r\n\r\n\t\t\t//2. Then save any fetched info\r\n\t\t\tif( responseData.data.data.FlightInfo){\r\n\r\n\t\t\t\tvar crew = responseData.data.data.FlightInfo.crew;\r\n\t\t\t\tCrewCallFactory.saveFlightPhoneNumbers(flightId, crew, flight.ScheduledArrival, flight.ScheduledDeparture);\r\n PreviousDutyFactory.saveFlightPreviousDuties(flightId, crew);\r\n\t\t\t}\r\n\r\n\t\t\t//Save pax\r\n\t\t\tif (responseData.data.data.CabinServiceManagementLists) {\r\n\t\t\t\tfor (var i = 0; i < responseData.data.data.CabinServiceManagementLists.length; i++) {\r\n\r\n\t\t\t\t\tif (responseData.data.data.CabinServiceManagementLists[i].FlightId == flightId) {\r\n\t\t\t\t\t\t//check for out of date range pax info\r\n\t\t\t\t\t\tvar today = new Date().getTime();\r\n\t\t\t\t\t\tvar paxDate = new Date(responseData.data.data.CabinServiceManagementLists[i].LastRun).getTime();\r\n\t\t\t\t\t\tif (paxDate <= today - 172800000) {\r\n\t\t\t\t\t\t\t$scope.showOnOutOfDateRange = true;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t$scope.pax = responseData.data.data.CabinServiceManagementLists[i];\r\n\t\t\t\t\t\t$scope.showOnSuccess = true;\r\n\t\t\t\t\t\tisThisFlightSynced = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!$scope.showOnSuccess) {\r\n\t\t\t\t\t$scope.showOnSuccessNoFlightData = true;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// $timeout(function () {\r\n\t\t\t\t// \t$uibModalInstance.close();\r\n\t\t\t\t// \t$route.reload();\r\n\t\t\t\t// }, 3000);\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t$scope.showOnEmptyData = true;\r\n\t\t\t}\r\n\t\t},\r\n\t\t\tfunction (responseData) {\r\n\t\t\t\tupdateStatusGenerator(responseData);\r\n\t\t\t\t$scope.isFetchingFlightData = !($scope.isFetchingFlightData);\r\n\t\t\t\t$scope.hideElements = false;\r\n\t\t\t});\r\n\r\n\r\n\t\tfunction updateStatusGenerator(data) {\r\n\t\t\tif (!data.data || !data.data.success) {\r\n\t\t\t\tfor (var i = 0; i < $scope.flightDataStatus.length; i++) {\r\n\t\t\t\t\t$scope.flightDataStatus[i].status = \"FAIL\";\r\n\t\t\t\t\t$scope.flightDataStatus[i].text = \"Update failed\";\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (!data.data.data.Campaigns.GetAssignmentsSuccess) {\r\n\t\t\t\t\t$scope.flightDataStatus[6].status = \"FAIL\";\r\n\t\t\t\t\t$scope.flightDataStatus[6].text = \"Update failed\";\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar newDuty = data.data.data;\r\n\t\t\t\tInfoAPIService.updateFlightStatusSetter(newDuty, $scope.flightDataStatus);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('turnAroundTimes',turnAroundTimes);\r\n\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name turnAroundTimes\r\n * @restrict EA\r\n * @description\r\n * Implementation of turnAroundTimes\r\n *\r\n * Initialize the turn Around Times panel needs to have flight in scope\r\n * @example\r\n * Usage:\r\n *
\r\n * @ngInject\r\n */ \r\nfunction turnAroundTimes(AircaftPositionsFactory,turnArroundTimesAcTypes) {\r\n \r\n /**\r\n * Initialize turnAroundTimes\r\n * @memberof turnAroundTimes\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\r\n function link ($scope, element, attrs) {\r\n $scope.showTaTpanel = false;\r\n \r\n var supportsTurnArroundTimes = $scope.flight && turnArroundTimesAcTypes.includes($scope.flight.AcType);\r\n\r\n if($scope.flight && $scope.flight.FlightId && $scope.flight.ATD && supportsTurnArroundTimes){\r\n var aircaftPositions = AircaftPositionsFactory.getAircaftPositionsByFlightId($scope.flight.FlightId);\r\n if(aircaftPositions != null && aircaftPositions.PreviousATA){\r\n /* var scheduledGroundTime = Date.DifferenceInMinutes(aircaftPositions.PreviousSTA, $scope.flight.ScheduledDeparture);\r\n var actualGroundTime = Date.DifferenceInMinutes(aircaftPositions.PreviousATA, $scope.flight.ScheduledDeparture);\r\n */ \r\n var std = moment.utc($scope.flight.ScheduledDeparture);\r\n var atd = moment.utc($scope.flight.ATD);\r\n var startofTAT = moment.utc($scope.flight.ScheduledDeparture).add(-45, 'm');\r\n var prevATA = moment.utc(aircaftPositions.PreviousATA);\r\n \r\n var lateArrival = prevATA.diff(startofTAT, 'm');\r\n var scheduledTurnAroundTime = std.diff(startofTAT,'m');\r\n \r\n var comparedValue = startofTAT;\r\n if(lateArrival > 0){\r\n var comparedValue = prevATA;\r\n }\r\n var actualTurnAroundTime = atd.diff(comparedValue,'m');\r\n \r\n $scope.scheduledTurnAroundTime = scheduledTurnAroundTime;\r\n $scope.actualTurnAroundTime = actualTurnAroundTime;\r\n $scope.lateArrival = lateArrival;\r\n $scope.showTaTpanel = true;\r\n }\r\n }\r\n\r\n }\r\n return {\r\n\t\t\trestrict: 'EA',\r\n\t\t\tterminal: true,\r\n templateUrl: 'views/directives/turnAroundTimes.tpl.html',\r\n\t\t\tscope : false,\r\n link: link \r\n }\r\n}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('AddFlightCtrl', AddFlightCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name AddFlightCtrl\r\n * @description \r\n * Add a new flight that is not in schedule\r\n * @ngInject\r\n */ \r\nfunction AddFlightCtrl($scope, UserFactory, FlightFactory, AircraftTypeFactory, $uibModalInstance, $route) {\r\n\r\n\t\t$scope.isSecure = UserFactory.isSecure();\r\n\r\n\t\t// cancel\r\n\t\t$scope.doCancel = doCancel;\r\n\r\n\r\n\t\t// add flight\r\n\t\t$scope.doAdd = doAdd;\r\n\t\t\r\n\r\n\t\t// setup datetime pickers\r\n\t\tvar now = new Date();\r\n\t\tvar minSelectableDate = new Date();\r\n\t\tvar maxSelectableDate = new Date();\r\n\t\tminSelectableDate.setDate(now.getDate() - 15);\r\n\t\tmaxSelectableDate.setDate(now.getDate() + 2);\r\n\t\t$scope.minSelectableDateStr = minSelectableDate.toString('dd-MM-yyyy');\r\n\t\t$scope.maxSelectableDateStr = maxSelectableDate.toString('dd-MM-yyyy');\r\n\t\t$scope.selectedDate = null;\r\n\t\t$scope.selectedTime = null;\r\n\r\n\t\t$scope.hstep = 1;\r\n\t\t$scope.mstep = 1;\r\n\t\t$scope.ismeridian = false;\r\n\r\n\t\t$scope.dateFormat = 'dd-MM-yyyy';\r\n\t\t$scope.hourFormat = \"HH:mm\"\r\n\r\n\t\t$scope.datepicker = {\r\n\t\t\topened: false\r\n\t\t};\r\n\r\n\r\n\t\t$scope.openDatepicker = openDatepicker;\r\n $scope.createFlightFromUIValues = createFlightFromUIValues; \r\n \r\n\t\t$scope.processForm = processForm;\r\n \r\n // initialize form data\r\n\t\t$scope.formData = {};\r\n \r\n // setup aircraft types\r\n\t\tvar actypes = AircraftTypeFactory.getAircraftTypesFromStorage();\r\n\t\tif (!(actypes instanceof Array)) actypes = [];\r\n actypes.push({\r\n\t\t\t Code: 'other'\r\n\t\t});\r\n \r\n\t\t$scope.aircraftTypes = actypes;\r\n\t\r\n /**\r\n * Open Datepicker\r\n * @memberof AddFlightCtrl\r\n */\r\n function openDatepicker() {\r\n\t\t\t$scope.datepicker.opened = true;\r\n\t\t}\r\n\r\n /**\r\n * Close the modal\r\n * @memberof AddFlightCtrl\r\n */\r\n function doCancel() {\r\n\t\t\t$uibModalInstance.close('cancel');\r\n\t\t} \r\n \r\n /**\r\n * Add the flight to schedule\r\n * @memberof AddFlightCtrl\r\n */\r\n function doAdd() {\r\n\t\t\t$scope.processForm();\r\n\t\t}\r\n\r\n \r\n /**\r\n * Get the values from ui and create a flight \r\n * @memberof AddFlightCtrl\r\n */\r\n\t\t// \r\n\t\tfunction createFlightFromUIValues() {\r\n\r\n\t\t\t// get moment dt from controls\r\n\t\t\tvar flightDate = $scope.formData.flightDateStr;\r\n\t\t\tvar flightSTD = $scope.formData.flightTimeStr;\r\n\t\t\t// convert them to dates\r\n\t\t\tflightDate = new Date(flightDate);\r\n\t\t\tflightSTD = new Date(flightSTD);\r\n\t\t\t// combine date and time\r\n\t\t\tflightDate.setHours(flightSTD.getHours(), flightSTD.getMinutes(), 0, 0);\r\n\t\t\t// flightDate = flightDate.fromUTC();\r\n\t\t\t// get other flight details\r\n\t\t\tvar flightNumber = $scope.formData.flightNumber;\r\n\t\t\tvar flightDeparture = $scope.formData.flightDeparture;\r\n\t\t\tvar flightDestination = $scope.formData.flightDestination;\r\n\t\t\tvar flightRegNo = $scope.formData.flightRegNo;\r\n\t\t\tvar flightAcType = null;\r\n\t\t\tif ($scope.formData.flightAcType != null)\r\n\t\t\t\tflightAcType = $scope.formData.flightAcType;\r\n\r\n\t\t\t// try to create a local flight\r\n\t\t\tvar newFlight = FlightFactory.createLocalFlight(flightDate, flightNumber, flightDeparture, flightDestination, flightRegNo, flightAcType);\r\n\r\n\t\t\treturn newFlight;\r\n\t\t}\r\n\r\n\r\n /**\r\n * Process and validate the form\r\n * @memberof AddFlightCtrl\r\n */\r\n\t\tfunction processForm() {\r\n\t\t\t// if all valid\r\n\t\t\tif ($scope.formFlight.$valid) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\t// try to create a local flight\r\n\t\t\t\t\tvar newFlight = $scope.createFlightFromUIValues();\r\n\r\n\t\t\t\t\t// save the local flight\r\n\t\t\t\t\tif (newFlight != null) {\r\n\t\t\t\t\t\tFlightFactory.saveLocalFlight(newFlight);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (newFlight == null) {\r\n\t\t\t\t\t\tbootbox.alert(\"

Error

Unable to create a flight record.\");\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t(function() {\r\n\t\t\t\t\t\t\t\t$uibModalInstance.close();\r\n\t\t\t\t\t\t\t\t$route.reload();\r\n\t\t\t\t\t\t\t\t})();\r\n\t\t\t\t\t}\r\n\t\t\t\t} catch (e) {\r\n\t\t\t\t\tbootbox.alert(\"

Error

Unable to create a flight record due to unexpected error:\\n\" + e.message);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tbootbox.alert(\"Please fill in all the required fields.\");\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t\r\n\r\n\t}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('CalendarCtrl', CalendarCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CalendarCtrl\r\n * @description \r\n * View your schedule (flights and ground duties)\r\n * @ngInject\r\n */\r\n function CalendarCtrl($scope, defaultCalendarDate, LeaveRequestFactory, version, $location,\r\n FlightFactory, UserFactory, MemoFactory, MessageFactory, UpdateService,\r\n SyncLogFactory, $timeout, $uibModal, CrewRouteFactory, CrewHotelFactory, GroundDutyFactory,\r\n localStorageMD5Service, SettingsMain, TrainingSessionFactory, FlightSessionFactory,\r\n ScheduleAcknowledgeFactory, CheckInFactory, ExpiriesFactory, $route, TraineeCoursesDetailsFactory, RequestFactory) {\r\n\r\n var flights = FlightFactory.getFlightsFromStorage();\r\n var user = UserFactory.getUser();\r\n var isAssessmentEnabled = SettingsMain.getIsAssessmentEnabled();\r\n\r\n $scope.isSecure = UserFactory.isSecure();\r\n $scope.state = 'calendar'; \r\n $scope.setupView = setupView;\r\n $scope.logged_user_info = user.aimsId + ' - ' + user.name;\r\n $scope.storageUsage = storageUsage();\r\n $scope.addFlight = addFlight;\r\n $scope.openSynch = openSynch;\r\n $scope.pendingOverdueReports = 0;\r\n $scope.draftReports = 0;\r\n $scope.completedReports = 0;\r\n $scope.isUserSA = user.position == 'SA' ? true : false;\r\n $scope.gotoUnreadMemos = gotoUnreadMemos;\r\n $scope.gotoMessages = gotoMessages;\r\n $scope.gotoLeaves = gotoLeaves;\r\n $scope.hasUnsetTraining = false;\r\n $scope.hasScheduleChanged = false;\r\n $scope.acknowledge = acknowledge;\r\n $scope.showPasswordExpiryAlert = false;\r\n $scope.showExpiriesAlertCalendar = false;\r\n $scope.showSubmissionDeadlineAlertCalendar = false;\r\n $scope.expiryList = [];\r\n $scope.submissionDeadline = null;\r\n $scope.showCheckInAction = false;\r\n $scope.openCheckIn = openCheckInModal;\r\n $scope.searchPastGroundDuties = searchPastGroundDuties;\r\n $scope.hasManualEntry = false;\r\n $scope.gotoGroundDutyInfo = gotoGroundDutyInfo;\r\n $scope.removeManualEntry = removeManualEntry;\r\n $scope.daysDiff = daysDiff;\r\n $scope.hasTraineeCourse = false;\r\n $scope.gotoFlightInfo = gotoFlightInfo;\r\n\r\n $scope.removeFlightTrainingManualEntry = removeFlightTrainingManualEntry;\r\n $scope.gotoCrewRouteInfo = gotoCrewRouteInfo;\r\n\r\n $scope.pastTrainingsViewSummary = pastTrainingsViewSummary;\r\n $scope.viewPastTrainings = false;\r\n $scope.removePendingGDEntry = removePendingGDEntry;\r\n $scope.removePendingFlightEntry = removePendingFlightEntry;\r\n\r\n $scope.passwordExpiry = {\r\n showAlert: false,\r\n lastChange: null,\r\n daysLeft: null \r\n };\r\n \r\n function pastTrainingsViewSummary() {\r\n $scope.viewPastTrainings = ! $scope.viewPastTrainings\r\n }\r\n var groundSessions = [];\r\n var flightSessions = [];\r\n TrainingSessionFactory.getAll(function (savedGroundSessions) {\r\n FlightSessionFactory.getAll(function (savedFlightSessions) {\r\n groundSessions = savedGroundSessions;\r\n flightSessions = savedFlightSessions;\r\n\r\n $scope.setupView(false);\r\n });\r\n });\r\n\r\n if (version) {\r\n $scope.version = version.replace('appVersion_', '');\r\n } else {\r\n $scope.version = '';\r\n }\r\n\r\n /**\r\n * Calculates the local storage Usage\r\n * @memberof CalendarCtrl\r\n * @return {string} usage\r\n */\r\n function storageUsage() {\r\n var usage = localStorageMD5Service.usedSize();\r\n return usage;\r\n }\r\n\r\n /**\r\n * Calculates days left\r\n * @memberof CalendarCtrl\r\n * @return {string} usage\r\n */\r\n function daysDiff(date) {\r\n var today = moment().startOf('day');\r\n var expiryDate = moment(date);\r\n\r\n return expiryDate.diff(today, 'days');\r\n }\r\n\r\n /**\r\n * Setups Calendar View\r\n * @memberof CalendarCtrl\r\n * @param {boolean} isReload\r\n */\r\n function setupView(isReload) {\r\n if (!UserFactory.isLoggedIn()) {\r\n $location.path(\"/login\");\r\n }\r\n\r\n $scope.NeedsToSync = UpdateService.updater();\r\n\r\n $scope.number_of_messages = MessageFactory.getMessagesFromStorage().length;\r\n\r\n $scope.number_of_messages_not_readen = MessageFactory.getCountOfUnreadMessages();\r\n\r\n $scope.leaveRequest = LeaveRequestFactory.getLeaveRequestInformation();\r\n\r\n $scope.leaveRequestCloseDate = $scope.leaveRequest ? moment($scope.leaveRequest.CloseDate).format('Do of MMMM') : null;\r\n\r\n $scope.expiryList = ExpiriesFactory.getCrewExpiriesFromStorage();\r\n \r\n $scope.submissionDeadline = RequestFactory.getSubmissionDeadlineDateFromStorage();\r\n\r\n //Get count of unread memos but remove the ones that belong in 'Training Surveys' Category\r\n MemoFactory.getUnreadMemos(function (memos) {\r\n $scope.unreadMemosCount = (memos && memos.length) || 0;\r\n });\r\n\r\n // read the flights from the local storage and display them\r\n var flights = FlightFactory.getFlightsFromStorageAndCheckIfTooOld();\r\n\r\n // also load the flights created by the user\r\n flights = FlightFactory.getLocalFlightsAndMergeWithServerFlights(flights);\r\n\r\n // if no local flights are found then force sync\r\n if (!isReload) {\r\n needsToSync = true;\r\n }\r\n\r\n var crewRoutes = CrewRouteFactory.getCrewRoutesFromStorage();\r\n var groundDuties = GroundDutyFactory.getGroundDutiesFromStorage();\r\n var crewHotels = CrewHotelFactory.getCrewHotelsFromStorage();\r\n var crewRoutesEvents = formatCrewRoutes(crewRoutes); \r\n \r\n var traineeGroundCourses = TraineeCoursesDetailsFactory.getTraineeCourses();\r\n\r\n var groundDutiesEvents = formatGroundDuties(groundDuties, traineeGroundCourses); \r\n \r\n // Get incomplete past duties\r\n $scope.totalIncompleteGD = [];\r\n $scope.totalIncompleteGD = groundDuties.filter(x => x.isManualEntry == true && !x.hasPendingCourse);\r\n\r\n \r\n // Flight duties\r\n $scope.totalIncompleteFlightDuties = [];\r\n $scope.totalIncompleteFlightDuties = crewRoutes.filter(x => x.isManualEntry && !x.hasPendingCourse);\r\n \r\n //\r\n \r\n if($scope.totalIncompleteGD.length > 0 || $scope.totalIncompleteFlightDuties.length > 0){\r\n $scope.showPastTrainingsSummary = true;\r\n }\r\n\r\n // Used for pending trainings notification \r\n $scope.manualGroundDuties = GroundDutyFactory.getManualGroundDutiesFromStorage();\r\n findManualEntries($scope.manualGroundDuties);\r\n\r\n $scope.manualFlightTrainings = CrewRouteFactory.getManualFlightTrainingsFromStorage();\r\n findManualFlightTrainingEntries($scope.manualFlightTrainings);\r\n \r\n var traineeFlightCourses = TraineeCoursesDetailsFactory.getFlightCourses();\r\n var flightEvents = formatFlights(flights, traineeFlightCourses);\r\n\r\n var crewHotelsEvents = formatHotels(crewHotels);\r\n\r\n var events = flightEvents.concat(groundDutiesEvents).concat(crewRoutesEvents).concat(crewHotelsEvents);\r\n\r\n var specialDates = findScheduleChangedDates();\r\n\r\n $scope.events = events;\r\n\r\n calendar(events, specialDates);\r\n \r\n var needsToSync = false;\r\n\r\n // check the last sync date\r\n var lastLog = SyncLogFactory.getSyncLog();\r\n var canShowSync = true;\r\n if (lastLog == null) {\r\n needsToSync = true;\r\n } else {\r\n canShowSync = lastLog.canShowSync(); //used to avoid showing again and again the dialog :: delay X minutes before showing again\r\n if (lastLog.date == null)\r\n needsToSync = true;\r\n else if (lastLog.date != null) {\r\n if (Date.today().add(-1).days().toUTC().isAfter(new Date(lastLog.date).toUTC()) || lastLog.forceSync) {\r\n if (!isReload)\r\n needsToSync = true;\r\n }\r\n }\r\n }\r\n\r\n var isOpenUpdateModal = ($(\".modal-updating\").data('bs.modal') || { isShown: false }).isShown;\r\n if (needsToSync && canShowSync && !isOpenUpdateModal) {\r\n $scope.openSynch();\r\n } else {\r\n MemoFactory.getMandatoryUnreadMemos(function (memos) {\r\n $scope.mandatoryUnread = memos.length;\r\n if ($scope.mandatoryUnread > 0) {\r\n openMandatoryModal();\r\n }\r\n });\r\n }\r\n\r\n $scope.showExpiriesAlertCalendar = showExpiriesAlertCalendar();\r\n $scope.showSubmissionDeadlineAlertCalendar = showSubmissionDeadlineAlertCalendar();\r\n $scope.showCheckInAction = showCheckInAction();\r\n preparePasswordExpiryData();\r\n showReminderModal();\r\n }\r\n\r\n\r\n /**\r\n * Finds the dates with a change on their schedule\r\n * @memberof CalendarCtrl\r\n * @returm {array} scheduleChangedDates\r\n */\r\n function findScheduleChangedDates() {\r\n var scheduleChangedDates = ScheduleAcknowledgeFactory.getScheduleChangesFromStorage();\r\n $scope.hasScheduleChanged = scheduleChangedDates.some(s => s);\r\n\r\n return scheduleChangedDates;\r\n }\r\n\r\n /**\r\n * Finds the dates with manual pending training entries on their schedule\r\n * @memberof CalendarCtrl \r\n */\r\n function findManualEntries(manualDuties) {\r\n for (var i = 0; i < manualDuties.length; i++) {\r\n if (manualDuties[i].hasPendingCourse) {\r\n $scope.hasManualEntry = true;\r\n break;\r\n }\r\n }\r\n }\r\n\r\n function findManualFlightTrainingEntries(manualFlightTrainings) { \r\n for (var i = 0; i < manualFlightTrainings.length; i++) {\r\n if (manualFlightTrainings[i].hasPendingCourse) {\r\n $scope.hasManualEntry = true;\r\n break;\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Initialize Calendar\r\n * @memberof CalendarCtrl\r\n * @param {array} events Flights and Ground duties \r\n * @param {array} specialDates The Schedule Changed Dates\r\n */\r\n function calendar(events, specialDates) {\r\n $(\"#calendar\").fullCalendar({\r\n defaultView: getDefaultView(),\r\n defaultDate: defaultCalendarDate,\r\n firstDay: 1,\r\n lang: 'en',\r\n editable: false,\r\n draggable: false,\r\n selectable: false,\r\n selectHelper: false,\r\n unselectAuto: false,\r\n disableResizing: false,\r\n droppable: false,\r\n fixedWeekCount: false,\r\n nextDayThreshold: \"00:00:00\",\r\n header: {\r\n left: 'title',\r\n center: '',\r\n right: 'month,listMonth today prev,next'\r\n },\r\n timeFormat: 'HH:mm',\r\n displayEventEnd: true,\r\n events: events,\r\n eventRender: function (event, element, icon) {\r\n if ($('#calendar').fullCalendar('getView').type === 'listMonth') {\r\n element.find('.fc-list-item-title').addClass('listview-icon');\r\n $.each(event.className, function (index, icon) {\r\n element.addClass(event.listViewColor);\r\n });\r\n // $.each(event.icons, function (index, icon) {\r\n // element.find('.listview-icon').prepend(\" \");\r\n // });\r\n\r\n\r\n if (!event.description == \"\") {\r\n element.find('.fc-list-item-title').append(\"\" + \" \" + event.description + \"\");\r\n }\r\n if (!event.icon == \"\") {\r\n element.find('.fc-list-item-title').append(\"\");\r\n }\r\n if (!event.second_icon == \"\") {\r\n element.find('.fc-list-item-title').append(\"\");\r\n }\r\n if(!event.third_icon == \"\") {\r\n element.find('.fc-list-item-title').append(\"\");\r\n }\r\n } else {\r\n if (event.type == \"crewRoute\" || event.type == \"hotel\") { \r\n element.find('.fc-time').remove();\r\n }\r\n\r\n element.find('.fc-title').prepend(\"
\");\r\n if (!event.description == \"\") {\r\n if(event.routeIndicators && event.routeIndicators.length >0){\r\n var routeIndicatorLetters = \"\";\r\n for (var j = 0; j < event.routeIndicators.length; j++) {\r\n var letter = \"\" + event.routeIndicators[j].routeIndicatorCode +\"\";\r\n routeIndicatorLetters = routeIndicatorLetters + letter;\r\n }\r\n\r\n element.find('.fc-title').append(\r\n \"
\" + event.description + \"\" + \r\n routeIndicatorLetters +\r\n \"
\");\r\n }\r\n else{\r\n element.find('.fc-title').append(\"
\" + event.description + \"
\");\r\n }\r\n }\r\n if (!event.icon == \"\") {\r\n element.find('.fc-title').append(\"\");\r\n }\r\n if (!event.second_icon == \"\") {\r\n element.find('.fc-title').append(\"\");\r\n }\r\n if(!event.third_icon == \"\") {\r\n element.find('.fc-title').append(\"\");\r\n }\r\n }\r\n\r\n },\r\n dayRender: function (date, cell) {\r\n for (var i = 0; i < specialDates.length; i++) {\r\n var objdate = new Date(specialDates[i]);\r\n if ((date._d.getFullYear() == objdate.getFullYear()) &&\r\n (date._d.getDate() == objdate.getDate()) &&\r\n (date._d.getMonth() == objdate.getMonth())\r\n )\r\n cell.addClass('bg-yellow');\r\n }\r\n },\r\n dayClick: function (date, jsEvent, view) { },\r\n eventClick: function (calEvent, jsEvent, view) {\r\n if (calEvent.type == \"flight\") {\r\n $timeout(function () {\r\n gotoFlightInfo(calEvent._id);\r\n });\r\n } else if (calEvent.type == \"groundDuty\") {\r\n $timeout(function () {\r\n gotoGroundDutyInfo(calEvent._id);\r\n });\r\n } else if (calEvent.type == \"crewRoute\") {\r\n $timeout(function () {\r\n gotoCrewRouteInfo(calEvent.dutyNo, calEvent.dutyDay);\r\n });\r\n }\r\n },\r\n height: 'auto'\r\n });\r\n\r\n function getDefaultView() {\r\n var calendarStyle = SettingsMain.getCalendarViewStyle();\r\n if (calendarStyle == null) {\r\n calendarStyle = detectMobile() ? \"listMonth\" : \"month\";\r\n }\r\n return calendarStyle;\r\n\r\n }\r\n\r\n function detectMobile() {\r\n var isMobile = (window.innerWidth <= 800 && window.innerHeight <= 735);\r\n\r\n return isMobile;\r\n }\r\n\r\n $('.fc-listMonth-button').click(function () {\r\n SettingsMain.setCalendarViewStyle('listMonth');\r\n })\r\n\r\n $('.fc-month-button').click(function () {\r\n SettingsMain.setCalendarViewStyle('month');\r\n })\r\n\r\n }\r\n\r\n /**\r\n * Transform flights in calendar events\r\n * @memberof CalendarCtrl\r\n * @param {array} flights The Scheduled Flights \r\n * @return {array} events \r\n */\r\n function formatFlights(flights, traineeFlightCourses) {\r\n var flightEvents = [];\r\n \r\n\r\n for (var i = 0; i < flights.length; i++) {\r\n var description = flights[i].getRoute();\r\n var title = flights[i].FlightNo;\r\n var third_icon =\"\";\r\n var flightCourseStatuses = [];\r\n var flightCoursesFlat = [];\r\n if (flights[i].TrainingIndicatorCode) {\r\n title = title + \" \" + flights[i].TrainingIndicatorCode;\r\n }\r\n\r\n /* Trainee flight courses */\r\n \r\n var relatedFlightTraineeCourses = [];\r\n for (var j = 0; j < traineeFlightCourses.length; j++){\r\n if(flights[i].IsTrainee == true && flights[i].FlightId == traineeFlightCourses[j].FlightId) {\r\n relatedFlightTraineeCourses = traineeFlightCourses.find(x => x.FlightId == flights[i].FlightId);\r\n \r\n flightCoursesFlat = flightCoursesFlat.concat(relatedFlightTraineeCourses);\r\n \r\n \r\n /* NotSet = 0,\r\n InProgress = 1,\r\n Completed = 2,\r\n Pending = 3,\r\n NeedsApproval = 4,\r\n NotCompleted = 5 \r\n */\r\n }\r\n \r\n if(flightCoursesFlat.length > 0){\r\n console.log(relatedFlightTraineeCourses);\r\n console.log(flightCourseStatuses);\r\n }\r\n \r\n }\r\n if (flightCoursesFlat.length > 0) {\r\n flightCoursesFlat.forEach(function (x) {\r\n flightCourseStatuses.push(x.Status);\r\n \r\n });\r\n }\r\n \r\n if (flightCourseStatuses.includes(1)) {\r\n //Pending\r\n third_icon = \"fa-graduation-cap text-blue\";\r\n } else if (flightCourseStatuses.includes(2)) {\r\n //Completed\r\n third_icon = \"fa-graduation-cap text-green\";\r\n } else if (flightCourseStatuses.includes(4) || flightCourseStatuses.includes(5)) {\r\n //Needs approval or stopped\r\n third_icon = \"fa-graduation-cap text-orange\";\r\n }\r\n\r\n var classname = \"\";\r\n var icon = \"fa-plane\";\r\n var second_icon = \"\";\r\n var id = flights[i].FlightId;\r\n var type = \"flight\";\r\n var listViewColor = \"\";\r\n\r\n /* Weights for status of reports\r\n 6 --> na\r\n 5 --> draft\r\n 4 --> pendingoverdue\r\n 3 --> pending\r\n 2 --> completed\r\n 1 --> synched */\r\n\r\n var CabinReportStatusWeight = 0;\r\n if (flights[i].LineStatus === 'na')\r\n CabinReportStatusWeight = 6;\r\n else if (flights[i].LineStatus === 'pending')\r\n CabinReportStatusWeight = 3;\r\n else if (flights[i].LineStatus === 'pendingoverdue') {\r\n CabinReportStatusWeight = 4;\r\n $scope.pendingOverdueReports++;\r\n } else if (\r\n (flights[i].LineStatus === 'draft') ||\r\n (flights[i].LineStatus === 'draftotheruser')\r\n ) {\r\n $scope.draftReports++;\r\n CabinReportStatusWeight = 5;\r\n } else if (\r\n (flights[i].LineStatus === 'completed') ||\r\n (flights[i].LineStatus === 'completedotheruser')\r\n ) {\r\n $scope.completedReports++;\r\n CabinReportStatusWeight = 2;\r\n } else if (\r\n (flights[i].LineStatus === 'stored') ||\r\n (flights[i].LineStatus === 'storedotheruser') ||\r\n (flights[i].LineStatus === 'stored+otheruser') ||\r\n (flights[i].LineStatus === 'synched') ||\r\n (flights[i].LineStatus === 'synchedotheruser')\r\n ) {\r\n CabinReportStatusWeight = 1;\r\n }\r\n //Remove Assessment Weight For Coloring\r\n /* var AssessmentStatusWeight = 0;\r\n if (isAssessmentEnabled && flights[i].assessment){\r\n if(flights[i].assessment.IsExist || flights[i].assessment.Status == 'Stored'){\r\n AssessmentStatusWeight = 1\r\n }else if(flights[i].assessment.Status == 'Completed'){\r\n AssessmentStatusWeight = 2;\r\n }else if(flights[i].assessment.Status == 'Pending'){\r\n AssessmentStatusWeight = 3;\r\n }else if(flights[i].assessment.Status == 'Draft'){\r\n AssessmentStatusWeight = 5;\r\n }\r\n }*/\r\n\r\n var statusWeight = CabinReportStatusWeight;\r\n // var statusWeight = CabinReportStatusWeight > AssessmentStatusWeight ? CabinReportStatusWeight : AssessmentStatusWeight;\r\n\r\n if (statusWeight == 6) {\r\n if (flights[i].IsDHC) {\r\n classname = \"fc-aluminum\";\r\n icon = \"\";\r\n listViewColor = \"lv-aluminium\";\r\n } else{\r\n classname = \"fc-white\";\r\n icon = \"\";\r\n listViewColor = \"lv-white\";\r\n }\r\n } else if (statusWeight == 5) {\r\n classname = \"fc-orange\";\r\n icon = \"fa-pencil\";\r\n listViewColor = \"lv-orange\";\r\n } else if (statusWeight == 4) {\r\n classname = \"fc-seablue\";\r\n icon = \"fa-exclamation-triangle text-lemon\";\r\n listViewColor = \"lv-seablue\";\r\n } else if (statusWeight == 3) {\r\n classname = \"fc-blue\";\r\n icon = \"fa-plus\";\r\n listViewColor = \"lv-blue\";\r\n } else if (statusWeight == 2) {\r\n classname = \"fc-purple\";\r\n icon = \"fa-check-circle\";\r\n listViewColor = \"lv-purple\";\r\n } else if (statusWeight == 1) {\r\n classname = \"fc-green\";\r\n icon = \"fa-cloud-download\";\r\n listViewColor = \"lv-green\";\r\n }\r\n\r\n if (flights[i].IsScheduleChanged && flights[i].LineStatus != 'na') {\r\n classname = classname + \" text-yellow-important\";\r\n }\r\n\r\n if (\r\n (flights[i].LineStatus === 'draftotheruser') ||\r\n (flights[i].LineStatus === 'completedotheruser') ||\r\n (flights[i].LineStatus === 'synchedotheruser') ||\r\n (flights[i].LineStatus === 'storedotheruser') ||\r\n (flights[i].LineStatus === 'stored+otheruser')\r\n )\r\n second_icon = \"fa-user\";\r\n\r\n var IsScheduleChanged = flights[i].IsScheduleChanged;\r\n var ScheduledDeparture = flights[i].ScheduledDeparture\r\n\r\n if (flights[i].ScheduledArrival == null) {\r\n var ScheduledArrival = ScheduledDeparture;\r\n } else {\r\n var ScheduledArrival = flights[i].ScheduledArrival\r\n }\r\n\r\n var event = {\r\n _id: id,\r\n title: title,\r\n start: ScheduledDeparture,\r\n end: ScheduledArrival,\r\n description: description,\r\n icon: icon,\r\n second_icon: second_icon,\r\n className: classname,\r\n type: type,\r\n isScheduleChanged: IsScheduleChanged,\r\n listViewColor: listViewColor,\r\n third_icon: third_icon\r\n };\r\n flightEvents.push(event)\r\n }\r\n return flightEvents;\r\n }\r\n\r\n /**\r\n * Transform Ground Duties in calendar events\r\n * @memberof CalendarCtrl\r\n * @param {array} duties The Scheduled Ground Duties \r\n * @return {array} events \r\n */\r\n function formatGroundDuties(duties, traineeGroundCourses) {\r\n var groundEvents = [];\r\n var now = moment.utc();\r\n\r\n for (var i = 0; i < duties.length; i++) {\r\n var description = duties[i].Code;\r\n var title = (duties[i].Title) ? duties[i].Title : duties[i].Duty;\r\n\r\n var classname = \"fc-white\";\r\n\r\n var icon = \"\";\r\n var second_icon = \"\";\r\n\r\n if (duties[i].RelatedGroundDuties && duties[i].RelatedGroundDuties.length > 1) {\r\n icon = \"fa-graduation-cap\" // icon only if training\r\n\r\n //Get ground courses\r\n var courseStatuses = [];\r\n var coursesFlat = [];\r\n for (var j = 0; j < duties[i].RelatedGroundDuties.length; j++) {\r\n /* Trainee ground courses */\r\n if(traineeGroundCourses.length > 0){\r\n var relatedTraineeCourse = traineeGroundCourses.find(x => x.GroundDutyId == duties[i].Id);\r\n }\r\n var relatedDutyCourse = duties[i].RelatedGroundDuties[j].Courses;\r\n \r\n if (relatedDutyCourse) {\r\n coursesFlat = coursesFlat.concat(relatedDutyCourse);\r\n }\r\n\r\n if (relatedTraineeCourse) {\r\n coursesFlat = coursesFlat.concat(relatedTraineeCourse);\r\n }\r\n\r\n coursesFlat.forEach(function (x) {\r\n courseStatuses.push(x.Status);\r\n })\r\n \r\n } \r\n \r\n /*Statuses\r\n Completed : session has been sent\r\n Outdated :\tsession submission is overdue\r\n Draft\t : session completion has started but not submitted\r\n Pending : session submission not yet due\r\n */ \r\n\r\n /* NotSet = 0,\r\n InProgress = 1,\r\n Completed = 2,\r\n Pending = 3,\r\n NeedsApproval = 4,\r\n NotCompleted = 5 \r\n */\r\n if (courseStatuses.includes(\"Pending\") || courseStatuses.includes(1)) {\r\n //Pending\r\n classname = \"fc-blue-inverted\"\r\n\r\n //Outdated\r\n var dutyEnd = moment.utc(duties[i].DutyEnd);\r\n var duration = moment.duration(now.diff(dutyEnd)).asHours();\r\n if (duration > 1) {\r\n if (courseStatuses.includes(\"Pending\") || courseStatuses.includes('1')) $scope.hasUnsetTraining = true;\r\n classname = \"fc-seablue-inverted\"\r\n second_icon = \"fa-exclamation-triangle text-yellow second-icon-training\";\r\n // isManualEntry = true;\r\n }\r\n\r\n //Draft\r\n var courseId = coursesFlat[0].CourseId; // Fix msis // each duty should contain ONLY ONE COURSE\r\n var duty = duties[i];\r\n\r\n if (groundSessions && groundSessions.length) {\r\n var existingSession = groundSessions.find(s => s.courseId == courseId && s.day == duty.DutyDateS && s.dutyId == duty.Id);\r\n if (existingSession && !existingSession.HasLimitedInfo && existingSession.trainees && existingSession.trainees.length) {\r\n //a training session with trainees exists\r\n classname = \"fc-orange-inverted\";\r\n icon = \"fa-graduation-cap\";\r\n second_icon = \"\";\r\n // isManualEntry = true;\r\n }\r\n }\r\n } else if (courseStatuses.includes(\"Completed\") || courseStatuses.includes(2)) {\r\n //Completed\r\n classname = \"fc-green-inverted \";\r\n }\r\n else if(courseStatuses.includes(4) || courseStatuses.includes(5)) {\r\n //Needs approval or stopped\r\n classname = \"fc-orange-inverted\";\r\n }\r\n }\r\n\r\n if (duties[i].Unread) {\r\n second_icon = \"fa-envelope text-orange\";\r\n }\r\n\r\n var id = duties[i].Id;\r\n var type = \"groundDuty\";\r\n var start = (duties[i].DutyBegin) ? duties[i].DutyBegin : ((duties[i].DutyDateS) ? duties[i].DutyDateS : duties[i].DutyDate);\r\n var end = duties[i].DutyEnd;\r\n var listViewColor = \"lv-white\";\r\n\r\n var event = {\r\n _id: id,\r\n title: title,\r\n start: start,\r\n end: end,\r\n description: description,\r\n icon: icon,\r\n second_icon: second_icon,\r\n className: classname,\r\n type: type,\r\n listViewColor: listViewColor\r\n };\r\n\r\n groundEvents.push(event);\r\n }\r\n return groundEvents;\r\n }\r\n\r\n /**\r\n * Transform Crew Routes in calendar events\r\n * @memberof CalendarCtrl\r\n * @param {array} routes The Scheduled Crew Routes \r\n * @return {array} events \r\n */\r\n function formatCrewRoutes(routes) {\r\n var crewRouteEvents = [];\r\n var now = moment.utc();\r\n\r\n for (var i = 0; i < routes.length; i++) {\r\n var description = routes[i].Route;\r\n // var title = (duties[i].Title)? duties[i].Title : duties[i].Duty;\r\n var classname = \"fc-white\";\r\n var icon = \"\";\r\n var second_icon = \"\";\r\n\r\n var assessmentStatus = \"\";\r\n if (isAssessmentEnabled && routes[i].AssessmentInfo) {\r\n if (routes[i].AssessmentInfo.IsExist || routes[i].AssessmentInfo.Status == \"Stored\") {\r\n assessmentStatus = \"Synced\";\r\n //classname = \"fc-green-inverted \";\r\n } else if (routes[i].AssessmentInfo.Status == \"Pending\") {\r\n assessmentStatus = \"Pending\";\r\n //classname = \"fc-blue-inverted\";\r\n } else if (routes[i].AssessmentInfo.Status == \"Draft\") {\r\n assessmentStatus = \"Draft\";\r\n //classname = \"fc-orange-inverted\";\r\n } else if (routes[i].AssessmentInfo.Status == \"Completed\") {\r\n assessmentStatus = \"Completed\";\r\n //classname = \"fc-purple-inverted\";\r\n }\r\n }\r\n\r\n //Get ground courses\r\n var courseStatuses = [];\r\n var courses = routes[i].Courses;\r\n\r\n courses.forEach(function (x) {\r\n courseStatuses.push(x.Status)\r\n });\r\n\r\n /*Statuses\r\n Completed : session has been sent\r\n Outdated :\tsession submission is overdue\r\n Draft\t : session completion has started but not submitted\r\n Pending : session submission not yet due\r\n */\r\n\r\n var trainingStatus = \"\";\r\n if (courseStatuses.includes(\"Pending\")) {\r\n //Pending\r\n trainingStatus = \"Pending\";\r\n\r\n //Outdated\r\n var dutyEnd = moment.utc(routes[i].DutyEnd);\r\n var duration = moment.duration(now.diff(dutyEnd)).asHours();\r\n if (duration > 1) {\r\n if (courseStatuses.includes(\"Pending\")) $scope.hasUnsetTraining = true;\r\n trainingStatus = \"Outdated\";\r\n }\r\n\r\n //Draft\r\n var courseIds = courses.map(x => x.CourseId);\r\n var route = routes[i];\r\n\r\n if (flightSessions && flightSessions.length) {\r\n //TODO msis fix\r\n var dutyBegin = new moment(route.DutyBegin).format(\"YYYY-MM-DD\");\r\n var dutyEnd = new moment(route.DutyEnd).format(\"YYYY-MM-DD\");\r\n var existingSessions = flightSessions.filter(s => courseIds.includes(s.courseId) && (new moment(s.day).isSame(dutyBegin) || new moment(s.day).isSame(dutyEnd) || new moment(s.day).isBetween(dutyBegin, dutyEnd)) &&\r\n s.dutyDay == route.DutyDay && s.dutyNo == route.DutyNo);\r\n if (existingSessions && existingSessions.some(x => !x.HasLimitedInfo && x.trainees && x.trainees.length)) {\r\n //a training session with trainees exists\r\n trainingStatus = \"Draft\";\r\n }\r\n }\r\n } else if (courseStatuses.includes(\"Completed\")) {\r\n //Completed\r\n trainingStatus = \"Completed\";\r\n classname = \"fc-green-inverted \";\r\n }\r\n\r\n\r\n // Status outcome form bot assessment and training\r\n if (trainingStatus == \"Outdated\") {\r\n second_icon = \"fa-exclamation-triangle text-yellow second-icon-training\";\r\n classname = \"fc-seablue-inverted\";\r\n } else if (trainingStatus == \"Draft\" || assessmentStatus == \"Draft\") {\r\n classname = \"fc-orange-inverted\";\r\n } else if (trainingStatus == \"Pending\" || assessmentStatus == \"Pending\") {\r\n classname = \"fc-blue-inverted\";\r\n } else if (assessmentStatus == \"Completed\") {\r\n classname = \"fc-purple-inverted\";\r\n } else if (trainingStatus == \"Completed\" || assessmentStatus == \"Synced\") {\r\n classname = \"fc-green-inverted\";\r\n }\r\n\r\n if (courses && courses.length) {\r\n icon = \"fa-graduation-cap\";\r\n }\r\n\r\n var routeIndicators = [];\r\n if(routes[i].RouteIndicators){\r\n // Swap : [RECTYPE] = 106\r\n // Pre-Assigned : [RECTYPE] = 1\r\n // Requested : [RECTYPE] = 100\r\n var routeIndicatorCodes = routes[i].RouteIndicators.split(',').map(Number);\r\n for (var j = 0; j < routeIndicatorCodes.length; j++) {\r\n var routeIndicatorCode = \"\";\r\n var routeIndicatorColor= \"\";\r\n \r\n if(routeIndicatorCodes[j]){\r\n \r\n if(routeIndicatorCodes[j] == 106){\r\n routeIndicatorCode = \"S\";\r\n routeIndicatorColor = \"text-purple\";\r\n }\r\n else if(routeIndicatorCodes[j] == 1){\r\n routeIndicatorCode = \"P\";\r\n routeIndicatorColor = \"text-teal\";\r\n }\r\n else if(routeIndicatorCodes[j] == 100){\r\n routeIndicatorCode = \"R\";\r\n }\r\n if( routeIndicatorCode.length >0){\r\n routeIndicators.push({routeIndicatorCode:routeIndicatorCode, routeIndicatorColor: routeIndicatorColor})\r\n }\r\n }\r\n }\r\n }\r\n\r\n // var id = routes[i].Id;\r\n var type = \"crewRoute\";\r\n var dutyNo = routes[i].DutyNo;\r\n var dutyDay = routes[i].DutyDay;\r\n var start = (routes[i].DutyBegin) ? routes[i].DutyBegin : ((routes[i].DutyDateS) ? routes[i].DutyDateS : routes[i].DutyDate);\r\n var end = routes[i].DutyEnd;\r\n var listViewColor = \"lv-white\";\r\n\r\n var event = {\r\n // _id:id,\r\n // title: title,\r\n dutyNo: dutyNo,\r\n dutyDay: dutyDay,\r\n start: start,\r\n end: end,\r\n description: description,\r\n icon: icon,\r\n second_icon: second_icon,\r\n className: classname,\r\n type: type,\r\n listViewColor: listViewColor,\r\n routeIndicators: routeIndicators\r\n };\r\n\r\n crewRouteEvents.push(event);\r\n }\r\n return crewRouteEvents;\r\n }\r\n\r\n /**\r\n * Transform Crew Hotels in calendar events\r\n * @memberof CalendarCtrl\r\n * @param {array} crew hotels \r\n * @return {array} events \r\n */\r\n function formatHotels(hotels) {\r\n var crewRouteEvents = [];\r\n for (var i = 0; i < hotels.length; i++) {\r\n //var description = hotels[i].HotelName;\r\n var title = hotels[i].HotelName;\r\n var classname = \"fc-gray-inverted\";\r\n\r\n var icon = \"fa-bed\";\r\n var second_icon = \"\";\r\n // var id = routes[i].Id;\r\n var type = \"hotel\";\r\n var start = moment(hotels[i].DutyDate).endOf('day').toJSON();\r\n // var end = hotels[i].DutyDate;\r\n var listViewColor = \"lv-white\";\r\n\r\n var event = {\r\n // _id:id,\r\n title: title,\r\n start: start,\r\n end: start,\r\n //description:description,\r\n icon: icon,\r\n second_icon: second_icon,\r\n className: classname,\r\n type: type,\r\n listViewColor: listViewColor\r\n };\r\n\r\n crewRouteEvents.push(event);\r\n }\r\n return crewRouteEvents;\r\n }\r\n\r\n /** Removes manual training entry */\r\n function removeManualEntry(groundDuty) {\r\n GroundDutyFactory.removeGroundDuty(groundDuty);\r\n $route.reload();\r\n }\r\n\r\n /**\r\n * Removes manual flight training entry \r\n * @param {*} dutyNo \r\n * @param {*} dutyDay \r\n */\r\n function removeFlightTrainingManualEntry(dutyNo, dutyDay) {\r\n CrewRouteFactory.removeFlightTraining(dutyNo, dutyDay);\r\n setupView();\r\n $route.reload();\r\n }\r\n\r\n function removePendingGDEntry(groundDuty){\r\n $scope.totalIncompleteGD.find(x => x.Id == groundDuty).isManualEntry = false;\r\n GroundDutyFactory.removeGroundDuty(groundDuty);\r\n return $scope.totalIncompleteGD; \r\n }\r\n\r\n function removePendingFlightEntry(dutyNo, dutyDay){\r\n $scope.totalIncompleteFlightDuties.find(x => x.FlightId == dutyNo).isManualEntry = false;\r\n return $scope.totalIncompleteFlightDuties; \r\n }\r\n\r\n /**\r\n * Open Synch Modal\r\n * @memberof CalendarCtrl\r\n */\r\n function openSynch() {\r\n //store last time the sync dialog was displayed\r\n SyncLogFactory.setLastShow();\r\n\r\n openSynchModal();\r\n }\r\n\r\n function openSynchModal() {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgSynch.html',\r\n controller: 'SynchCtrl',\r\n size: 'lg',\r\n backdrop: 'static',\r\n keyboard: false\r\n });\r\n\r\n modalInstance.result.then(function (synchresult) {\r\n //refresh the view after a successful sync\r\n if (!synchresult == 'cancel') {\r\n $scope.setupView(true);\r\n }\r\n }, function () { });\r\n }\r\n\r\n function openMandatoryModal() {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgMandatory.html',\r\n controller: 'MandatoryModalCtrl',\r\n size: 'md',\r\n backdrop: 'static',\r\n keyboard: false,\r\n resolve: { mandatoryUnread: $scope.mandatoryUnread }\r\n });\r\n }\r\n\r\n /**\r\n * Open the \"Add a flight\" Modal\r\n * @memberof CalendarCtrl\r\n */\r\n function addFlight() {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgAddFlight.html',\r\n controller: 'AddFlightCtrl',\r\n size: 'lg',\r\n backdrop: 'static',\r\n keyboard: false\r\n });\r\n }\r\n\r\n /**\r\n * Open the \"Search Ground Duties\" Modal\r\n * @memberof CalendarCtrl\r\n */\r\n function searchPastGroundDuties() {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgSearchGroundDuties.html',\r\n controller: 'SearchPastGDCtrl',\r\n size: 'md',\r\n backdrop: 'static',\r\n keyboard: false\r\n });\r\n }\r\n\r\n function acknowledge() {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgAcknowledgeChanges.html',\r\n controller: 'AcknowledgeModalCtrl',\r\n size: 'lg',\r\n backdrop: 'static',\r\n keyboard: false\r\n });\r\n }\r\n\r\n\r\n /**\r\n * Gets showExpiriesAlert value\r\n * @memberof calendarNotifications\r\n */\r\n function showExpiriesAlertCalendar() {\r\n return ExpiriesFactory.showExpiriesAlert();\r\n }\r\n\r\n /**\r\n * Gets showSubmissionDeadlineAlert value\r\n * @memberof calendarNotifications\r\n */\r\n function showSubmissionDeadlineAlertCalendar() {\r\n return RequestFactory.showSubmissionDeadlineAlert();\r\n }\r\n\r\n function showCheckInAction() {\r\n var retVal = false;\r\n var checkInInfo = CheckInFactory.getCheckInInfoFromStorage();\r\n if (checkInInfo && checkInInfo.AimsId > 0) {\r\n var now = moment.utc();\r\n\r\n //Fetch FROM\r\n //Convert from Date UTC to Moment UTC\r\n\r\n var std = moment.utc(checkInInfo.STD);\r\n var minFetchTime = moment(std).add(-2, 'hours');\r\n\r\n //Fetch UNTIL \r\n var maxFetchTime = moment(std).add(10, 'minutes');\r\n\r\n var isAfter = now.isAfter(minFetchTime);\r\n var isBefore = now.isBefore(maxFetchTime);\r\n\r\n if (isAfter && isBefore) {\r\n retVal = true;\r\n }\r\n\r\n //console.log({\"isAfter\":isAfter, \"isBefore\": isBefore, \"now\":now, \"std\":std, \"minFetchTime\":minFetchTime,\"maxFetchTime\":maxFetchTime});\r\n\r\n }\r\n return retVal;\r\n }\r\n\r\n function preparePasswordExpiryData() {\r\n //update PasswordExpiry scope:\r\n var user = UserFactory.getUser();\r\n if(user && user.passwordLastChangeDate){\r\n \r\n var today = new Date();\r\n var lastChangeDate = new Date(user.passwordLastChangeDate);\r\n var expirationDate = lastChangeDate.AddDays(90);\r\n // how many days until duty date\r\n var diffDays = Date.DifferenceInDays(today.trimTime(), expirationDate.trimTime());\r\n \r\n $scope.passwordExpiry = {\r\n showAlert: diffDays && diffDays <= 14,\r\n lastChange: lastChangeDate,\r\n daysLeft: diffDays \r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Shows the bootbox for schedule acknowledge reminder\r\n * @memberof calendarNotifications\r\n */\r\n function showReminderModal() {\r\n\r\n var showScheduleChangesReminder = ScheduleAcknowledgeFactory.showScheduleChangesModal();\r\n var showExpiriesReminder = ExpiriesFactory.showExpiriesModal();\r\n var showSubmissionDeadlineReminder = RequestFactory.showSubmissionDeadlineModal();\r\n\r\n if (showScheduleChangesReminder || showExpiriesReminder || showSubmissionDeadlineReminder) {\r\n\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgReminderModal.html',\r\n controller: 'ReminderModalCtrl',\r\n size: 'md',\r\n backdrop: 'static',\r\n keyboard: false,\r\n resolve: {\r\n showScheduleChangesReminder: function () {\r\n return showScheduleChangesReminder;\r\n },\r\n showExpiriesReminder: function () {\r\n return showExpiriesReminder;\r\n },\r\n showSubmissionDeadlineReminder: function () {\r\n return showSubmissionDeadlineReminder;\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Open Check in Modal\r\n * @memberof CalendarCtrl\r\n */\r\n function openCheckInModal() {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgCheckIn.html',\r\n controller: 'CheckInModalCtrl',\r\n size: 'lg',\r\n backdrop: 'static',\r\n keyboard: false\r\n });\r\n }\r\n\r\n\r\n /**\r\n * Redirect to flight Info\r\n * @memberof CalendarCtrl\r\n */\r\n function gotoFlightInfo(FlightId) {\r\n $location.path('/flightinfo/' + FlightId);\r\n }\r\n\r\n /**\r\n * Redirect to groundDuty Info\r\n * @memberof CalendarCtrl\r\n */\r\n function gotoGroundDutyInfo(GroundDutyId) {\r\n $location.path('/groundDuty/' + GroundDutyId);\r\n }\r\n\r\n /**\r\n * Redirect to crewRoute Info\r\n * @memberof CalendarCtrl\r\n */\r\n function gotoCrewRouteInfo(dutyNo, dutyDay) {\r\n $location.path('/crewRoute/' + dutyNo + '/' + dutyDay);\r\n }\r\n\r\n /**\r\n * Redirect to crewRoute Info\r\n * @memberof CalendarCtrl\r\n */\r\n function gotoCrewRouteInfo(dutyNo, dutyDay) {\r\n $location.path('/crewRoute/' + dutyNo + '/' + dutyDay);\r\n }\r\n\r\n /**\r\n * Redirect to Library Info with filter enabled\r\n * @memberof CalendarCtrl\r\n */\r\n function gotoUnreadMemos() {\r\n $location.path('/memos/unread');\r\n }\r\n\r\n /**\r\n * Redirect to messages\r\n * @memberof CalendarCtrl\r\n */\r\n function gotoMessages() {\r\n $location.path('/messages/');\r\n }\r\n\r\n /**\r\n * Redirect to leaves\r\n * @memberof CalendarCtrl\r\n */\r\n function gotoLeaves() {\r\n $location.path('/leaverequest/');\r\n }\r\n }\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.factory('FlightFactory', FlightFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightFactory\r\n * @description \r\n * Add, Update, Delete and Get Flights \r\n * @ngInject\r\n */\r\n\tfunction FlightFactory($log, $filter, localStorageMD5Service, UserFactory, CabinReportLocalEditFactory, ServerCabinReportFactory, FlightCrewMemberFactory, MessageFactory, liveVersion, GenericService, SyncLogFactory) {\r\n\r\n\t\tvar daysThatAFlightIsConsideredTooOld = -20;\r\n\r\n /**\r\n * Initialize the Flight\r\n * @memberof FlightFactory\r\n */\r\n\t\tfunction Flight() {\r\n\t\t\tthis.AcTailNo = null;\r\n\t\t\tthis.AcType = null;\r\n\t\t\tthis.Category = null;\r\n\t\t\tthis.CrewAimsId = null;\r\n\t\t\tthis.Departure = null;\r\n\t\t\tthis.Arrival = null;\r\n\t\t\tthis.FlightAimsId = null;\r\n\t\t\tthis.FlightId = null;\r\n\t\t\tthis.FlightDate = null;\r\n\t\t\tthis.FlightNo = null;\r\n\t\t\tthis.IsDHC = null;\r\n\t\t\tthis.Position = null;\r\n\t\t\t//v1.1 added pax and dep/arr details\r\n\t\t\tthis.BookedC = null;\r\n\t\t\tthis.BookedY = null;\r\n\t\t\tthis.BookedInf = null;\r\n\t\t\tthis.BookedPad = null;\r\n\t\t\tthis.BookedChld = null;\r\n\t\t\tthis.ActualC = null;\r\n\t\t\tthis.ActualY = null;\r\n\t\t\tthis.ActualInf = null;\r\n\t\t\tthis.ActualPad = null;\r\n\t\t\tthis.ActualChld = null;\r\n\t\t\tthis.DepartureICAO = null;\r\n\t\t\tthis.DepartureCountry = null;\r\n\t\t\tthis.DepartureName = null;\r\n\t\t\tthis.ArrivalICAO = null;\r\n\t\t\tthis.ArrivalCountry = null;\r\n\t\t\tthis.ArrivalName = null;\r\n\r\n\t\t\tthis.ScheduledDeparture = null;\r\n\t\t\tthis.Status = null;\r\n\t\t\tthis.LineStatus = null;\r\n\t\t\tthis.LineStatusDescr = null;\r\n\t\t\tthis.LocalReportId = null;\r\n\t\t\tthis.ServerReportLink = null;\r\n\t\t\tthis.ScheduledDepartureDateUTC = null;\r\n\t\t\tthis.ScheduledDepartureTimeUTC = null;\r\n\t\t\tthis.LocalReportHasNothingToReport = false;\r\n\t\t\tthis.ServerReportHasNothingToReport = false;\r\n\t\t\tthis.IsLocal = false;\r\n\t\t\tthis.cabinReports = [];\r\n\t\t\tthis.cabinReportStatusDescr = '';\r\n\t\t\tthis.crew = new Array();\r\n\r\n\t\t\t//new fields\r\n\t\t\tthis.DepartureGate = null;\r\n\t\t\tthis.DepartureTimezone = null;\r\n\t\t\tthis.ArrivalTimezone = null;\r\n\t\t\tthis.CallSign = null;\r\n\t\t\tthis.ScheduledArrival = null;\r\n\t\t\tthis.messages = null;\r\n\t\t\tthis.assessment = null;\r\n\t\t\tthis.Route = null;\r\n\t\t\tthis.DutyDate = null;\r\n\t\t\tthis.FlightsFilters = [];\r\n\t\t\tthis.ETA = null;\r\n\t\t\tthis.IsScheduleChanged = false;\r\n\t\t\t//zones\r\n\t\t\tthis.Zones = [];\r\n\t\t\t//\r\n\t\t\tthis.AircraftDifferences = [];\r\n\t\t\tthis.GetId = GetId;\r\n\t\t\tthis.getRoute = getRoute;\r\n\t\t\tthis.getDescription = getDescription;\r\n\t\t\tthis.getSeniorAttendantsCount = getSeniorAttendantsCount;\r\n\t\t\t//TODO REMOVE CHECK VALIDITY WITH NEW VIEW\r\n\t\t\tthis.initializeCabinReportStatus = initializeCabinReportStatus;\r\n\t\t\tthis.getCabinReportStatusDescr = getCabinReportStatusDescr;\r\n\t\t\tthis.getServerCabinReportForUser = getServerCabinReportForUser;\r\n\t\t\tthis.getServerCabinReportsByAnotherUser = getServerCabinReportsByAnotherUser;\r\n\t\t\tthis.initialize = initialize;\r\n\t\t}\r\n\r\n\t\tvar service =\r\n\t\t{\r\n\t\t\tgetFlightsFromStorage: getFlightsFromStorage,\r\n\t\t\tgetFlightFromTotalFlights: getFlightFromTotalFlights,\r\n\t\t\tfromObject: fromObject,\r\n\t\t\tfromObjectList: fromObjectList,\r\n\t\t\tgetFlightsFromStorageAndCheckIfTooOld: getFlightsFromStorageAndCheckIfTooOld,\r\n\t\t\tsetFlightsToStorage: setFlightsToStorage,\r\n\t\t\tstoreFlightsWithReportsAndMessages: storeFlightsWithReportsAndMessages,\r\n\t\t\tgetFlightFromStorage: getFlightFromStorage,\r\n\t\t\tgetFlightsByRoute: getFlightsByRoute,\r\n\t\t\tgetLocalFlightFromStorage: getLocalFlightFromStorage,\r\n\t\t\tcreateLocalFlight: createLocalFlight,\r\n\t\t\tsaveLocalFlight: saveLocalFlight,\r\n\t\t\tgetLocalFlightsAndMergeWithServerFlights: getLocalFlightsAndMergeWithServerFlights,\r\n\t\t\tupdateFlightFromReport: updateFlightFromReport,\r\n\t\t\tupdateFlight: updateFlight,\r\n\t\t\tmergeFlightInfo: mergeFlightInfo,\r\n\t\t\tmarkScheduleChangedFlights: markScheduleChangedFlights,\r\n\t\t\tinitializeFlights: initializeFlights,\r\n\t\t\tgetFlightsByDutyNo:getFlightsByDutyNo,\r\n\t\t\tgetFlightsWithStoredReport: getFlightsWithStoredReport,\r\n\t\t\tgetFlightsByFlightId: getFlightsByFlightId,\r\n\t\t\tinsertFlightsWithPendingTrainings: insertFlightsWithPendingTrainings,\r\n\t\t\tgetTheFirstAndTheLastFlightDates: getTheFirstAndTheLastFlightDates\r\n\t\t};\r\n\r\n\t\tvar objType = 'flights';\r\n\t\tvar objCallback = Flight;\r\n\r\n\t\t//Object Functions\r\n /**\r\n * Overide default get Id\r\n * @memberof FlightFactory\r\n * @returns {number} Id \r\n */\r\n\t\tfunction GetId() {\r\n\t\t\treturn this.FlightId;\r\n\t\t}\r\n /**\r\n * Get flight's Route\r\n * @memberof FlightFactory\r\n * @returns {string} route \r\n */\r\n\t\tfunction getRoute() {\r\n\t\t\tif (this.Departure == null && this.Arrival == null) return '-null-';\r\n\t\t\telse return (this.Departure || '?') + '-' + (this.Arrival || '?');\r\n\t\t}\r\n /**\r\n * Get flight's description\r\n * @memberof FlightFactory\r\n * @returns {string} description \r\n */\r\n\t\tfunction getDescription() {\r\n\t\t\tif (this.FlightNo == null && this.Departure == null && this.Arrival == null) return '-null-';\r\n\t\t\telse return (this.ScheduledDepartureDateUTC || '?') + ' ' + (this.FlightNo || '?') + ' ' + (this.Departure || '?') + '-' + (this.Arrival || '?');\r\n\t\t}\r\n /**\r\n * Get flight's Senior Attendants Count\r\n * @memberof FlightFactory\r\n * @returns {number} seniorAttendantsCount \r\n */\r\n\t\tfunction getSeniorAttendantsCount() {\r\n\t\t\tif (this.crew == null || this.crew.length == 0) return 0;\r\n\t\t\tvar count = 0;\r\n\t\t\tvar attendants = $filter('filter')(this.crew, {\r\n\t\t\t\tposition: 'SA',\r\n\t\t\t\tisDHC: false\r\n\t\t\t});\r\n\t\t\tif (attendants != null) count = attendants.length;\r\n\t\t\treturn count;\r\n\t\t}\r\n\r\n\t\tfunction insertFlightsWithPendingTrainings(flightsWithPendings){\r\n\t\t\tif(flightsWithPendings){\r\n\t\t\t\tvar flights = getFlightsFromStorage();\r\n\t\t\t\tvar flightIdsLS = flights.map(x=>x.FlightId);\r\n\t\t\t\tvar flightsToInsert = flightsWithPendings.filter(f=> !flightIdsLS.includes(f.FlightId));\r\n\t\t\t\tvar updatedFlightList = flights.concat(flightsToInsert);\r\n\t\t\t\tsetFlightsToStorage(updatedFlightList);\r\n\t\t\t}\r\n }\r\n\r\n /**\r\n * Initialize Cabin report Status\r\n * @memberof FlightFactory\r\n */\r\n\t\tfunction initializeCabinReportStatus() {\r\n\t\t\t// load the user\r\n\t\t\tvar user = UserFactory.getUser();\r\n\r\n\t\t\t//Cannot file a report when a problem with the user or if the\r\n\t\t\t//person is DHC on that flight\r\n\t\t\tif (user == null || this.IsDHC != 0) {\r\n\t\t\t\tthis.LineStatus = \"na\";\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\t//not an SA? Normally not allowed to file a report\r\n\t\t\t//UNLESS there is no SA on board\r\n\t\t\telse if (this.Position != 'SA' && this.getSeniorAttendantsCount() > 0 && this.AcType != \"AT4\") {\r\n\t\t\t\t//console.debug('FA with ' + this.getSeniorAttendantsCount() + ' SA(s) on board!');\r\n\t\t\t\tthis.LineStatus = \"na\";\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// initialize to pending\r\n\t\t\tthis.LineStatus = \"pending\";\r\n\r\n\t\t\t// check if there is a local edit report or a server report for this\r\n\t\t\t// flight\r\n\t\t\tvar serverReportForThisUser = this.getServerCabinReportForUser(user.aimsId);\r\n\t\t\tvar serverReportsByAnotherUser = this.getServerCabinReportsByAnotherUser(user.aimsId);\r\n\r\n\t\t\tvar hasServerReportForThisUser = serverReportForThisUser != null;\r\n\t\t\tvar hasServerReportsByAnotherUser = serverReportsByAnotherUser.length > 0;\r\n\r\n\t\t\tvar localReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(this.FlightId);\r\n\r\n\t\t\tthis.LocalReportId = null;\r\n\t\t\tthis.ServerReportLink = null;\r\n\r\n\t\t\t// if there is a local copy of the report\r\n\t\t\tif (localReport != null) {\r\n\t\t\t\tthis.LocalReportId = localReport.ReportGuid;\r\n\t\t\t\tthis.LocalReportHasNothingToReport = localReport.NothingToReport;\r\n\r\n\t\t\t\tif (localReport.Status === 'draft') {\r\n\t\t\t\t\tif (hasServerReportsByAnotherUser)\r\n\t\t\t\t\t\tthis.LineStatus = \"draftotheruser\";\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tthis.LineStatus = \"draft\";\r\n\t\t\t\t} else if (localReport.Status === 'completed') {\r\n\t\t\t\t\tif (hasServerReportsByAnotherUser)\r\n\t\t\t\t\t\tthis.LineStatus = \"completedotheruser\";\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tthis.LineStatus = \"completed\";\r\n\t\t\t\t} else if (localReport.Status === 'synched') {\r\n\t\t\t\t\tif (hasServerReportsByAnotherUser)\r\n\t\t\t\t\t\tthis.LineStatus = \"synchedotheruser\";\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tthis.LineStatus = \"synched\";\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif (hasServerReportsByAnotherUser)\r\n\t\t\t\t\t\tthis.LineStatus = \"draftotheruser\";\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\tthis.LineStatus = \"draft\";\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// if there is a server report by this and by another user\r\n\t\t\t\tif (hasServerReportForThisUser && hasServerReportsByAnotherUser) {\r\n\t\t\t\t\tthis.LineStatus = \"stored+otheruser\";\r\n\t\t\t\t\t// Something if this or any other user has something to\r\n\t\t\t\t\t// report\r\n\t\t\t\t\tthis.ServerReportHasNothingToReport = serverReportForThisUser.ReportedItems == 0;\r\n\t\t\t\t\tif (this.ServerReportHasNothingToReport) {\r\n\t\t\t\t\t\t// if nothing to report by this user, check if any other\r\n\t\t\t\t\t\t// user has something to report\r\n\t\t\t\t\t\tfor (var i = 0; i < serverReportsByAnotherUser.length; i++) {\r\n\t\t\t\t\t\t\tif (serverReportsByAnotherUser[i].ReportedItems > 0) {\r\n\t\t\t\t\t\t\t\tthis.ServerReportHasNothingToReport = false;\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t// if there is a server report for another user\r\n\t\t\t\telse if (hasServerReportsByAnotherUser) {\r\n\t\t\t\t\tthis.LineStatus = \"storedotheruser\";\r\n\r\n\t\t\t\t\tthis.ServerReportHasNothingToReport = true;\r\n\t\t\t\t\tfor (var i = 0; i < serverReportsByAnotherUser.length; i++) {\r\n\t\t\t\t\t\tif (serverReportsByAnotherUser[i].ReportedItems > 0) {\r\n\t\t\t\t\t\t\tthis.ServerReportHasNothingToReport = false;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t// if there is a server report for only this user\r\n\t\t\t\telse if (hasServerReportForThisUser) {\r\n\t\t\t\t\tthis.LineStatus = \"stored\";\r\n\t\t\t\t\tthis.ServerReportHasNothingToReport = serverReportForThisUser.ReportedItems == 0;\r\n\t\t\t\t}\r\n\t\t\t\t// no server report\r\n\t\t\t\telse {\r\n\t\t\t\t\tthis.LocalReportId = \"new\";\r\n\r\n\t\t\t\t\t// no server report found for this user, status is pending\r\n\t\t\t\t\tif (new Date(this.ScheduledDeparture) < new Date()) {\r\n\t\t\t\t\t\tthis.LineStatus = \"pendingoverdue\";\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tthis.LineStatus = \"pending\";\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t}\r\n\t\t}\r\n\r\n /**\r\n * Get Cabin Report Status Descr\r\n * @memberof FlightFactory\r\n * @returns {string} description \r\n */\r\n\t\tfunction getCabinReportStatusDescr() {\r\n\t\t\tif (this.LineStatus === 'na')\r\n\t\t\t\treturn \"n/a\";\r\n\t\t\telse if (this.LineStatus === 'pending')\r\n\t\t\t\treturn \"Pending\";\r\n\t\t\telse if (this.LineStatus === 'pendingoverdue')\r\n\t\t\t\treturn \"Pending\";\r\n\t\t\telse if (this.LineStatus === 'draft')\r\n\t\t\t\treturn \"Draft\";\r\n\t\t\telse if (this.LineStatus === 'completed')\r\n\t\t\t\treturn \"Completed\";\r\n\t\t\telse if (this.LineStatus === 'synched')\r\n\t\t\t\treturn \"Synched\";\r\n\t\t\telse if (this.LineStatus === 'draftotheruser')\r\n\t\t\t\treturn \"Draft +\";\r\n\t\t\telse if (this.LineStatus === 'completedotheruser')\r\n\t\t\t\treturn \"Completed +\";\r\n\t\t\telse if (this.LineStatus === 'synchedotheruser')\r\n\t\t\t\treturn \"Synched +\";\r\n\t\t\telse if (this.LineStatus === 'stored')\r\n\t\t\t\treturn \"Stored\";\r\n\t\t\telse if (this.LineStatus === 'storedotheruser')\r\n\t\t\t\treturn \"Stored\";\r\n\t\t\telse if (this.LineStatus === 'stored+otheruser')\r\n\t\t\t\treturn \"Stored +\";\r\n\t\t\telse\r\n\t\t\t\treturn this.LineStatus;\r\n\t\t}\r\n\r\n /**\r\n * Get Server CabinReport For the selected User\r\n * @memberof FlightFactory\r\n * @param {number} userAimsId The user aims Id\r\n * @return {object} cabinReport \r\n */\r\n\t\tfunction getServerCabinReportForUser(userAimsId) {\r\n\r\n\t\t\tif (this.cabinReports == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\tvar result = null;\r\n\r\n\t\t\tfor (var i = 0; i < this.cabinReports.length; i++) {\r\n\t\t\t\tif (this.cabinReports[i] != null) {\r\n\t\t\t\t\tif (this.cabinReports[i].AuthorAimsId == userAimsId) {\r\n\t\t\t\t\t\tresult = this.cabinReports[i];\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Get Server CabinReport For others than the selected User\r\n * @memberof FlightFactory\r\n * @param {number} userAimsId The user aims Id\r\n * @return {object} cabinReport \r\n */\r\n\t\tfunction getServerCabinReportsByAnotherUser(userAimsId) {\r\n\r\n\t\t\tif (this.cabinReports == null)\r\n\t\t\t\treturn new Array();\r\n\r\n\t\t\tvar result = new Array();\r\n\r\n\t\t\tfor (var i = 0; i < this.cabinReports.length; i++) {\r\n\t\t\t\tif (this.cabinReports[i] != null) {\r\n\t\t\t\t\tif (this.cabinReports[i].AuthorAimsId != userAimsId) {\r\n\t\t\t\t\t\tresult.push(this.cabinReports[i]);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\r\n /**\r\n * Initialize Cabin Report\r\n * @memberof FlightFactory\r\n */\r\n\t\tfunction initialize() {\r\n\t\t\ttry {\r\n\t\t\t\t// SD date/time\r\n\t\t\t\tif (this.ScheduledDeparture != null) {\r\n\t\t\t\t\tvar STD = this.ScheduledDeparture;\r\n\t\t\t\t\tif (STD.indexOf('Z') < 0)\r\n\t\t\t\t\t\tSTD += 'Z';\r\n\t\t\t\t\tSTD = new moment(STD);\r\n\t\t\t\t\tSTD = new Date(STD);\r\n\t\t\t\t\tSTD = STD.toUTC();\r\n\t\t\t\t\tthis.ScheduledDepartureDateUTC = STD.toString('yyyy-MM-dd');\r\n\t\t\t\t\tthis.ScheduledDepartureTimeUTC = STD.toString('HH:mm');\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// initialize the cabin report status field\r\n\t\t\t\tthis.initializeCabinReportStatus();\r\n\r\n\t\t\t\t// initialize css classes for display\r\n\t\t\t\tthis.cabinReportStatusDescr = this.getCabinReportStatusDescr();\r\n\t\t\t} catch (ex) {\r\n\t\t\t\t$log.error(\"initialize failed: \" + ex.message);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t//Factory Functions\r\n\r\n /**\r\n * Extend Object from the default Flight Object\r\n * @memberof FlightFactory\r\n * @param {Object} obj a Flight\r\n * @returns {Object} Flight\r\n */\r\n\t\tfunction fromObject(obj) {\r\n\t\t\tif (obj == null) return null;\r\n\t\t\tvar flight = new Flight();\r\n\t\t\tangular.extend(flight, obj);\r\n\r\n\t\t\tif (obj.crew == null)\r\n\t\t\t\tobj.crew = [];\r\n\r\n\t\t\tflight.crew = new Array();\r\n\t\t\tfor (var j = 0; j < obj.crew.length; j++) {\r\n\t\t\t\tflight.crew.push(FlightCrewMemberFactory.fromObject(obj.crew[j]));\r\n\t\t\t}\r\n\r\n\t\t\treturn flight;\r\n\t\t};\r\n\r\n /**\r\n * Extend an array of Objects from the default flight Object\r\n * @memberof FlightFactory\r\n * @param {Array} objList an Array Of flights\r\n * @returns {Array} flights\r\n */\r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\tif (objList == null) return [];\r\n\r\n\t\t\tvar arrayLength = objList.length;\r\n\t\t\tvar flights = new Array();\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tvar flight = new Flight();\r\n\t\t\t\tangular.extend(flight, objList[i]);\r\n\r\n\t\t\t\tif (objList[i].crew == null)\r\n\t\t\t\t\tobjList[i].crew = [];\r\n\r\n\r\n\t\t\t\tflights.push(flight);\r\n\t\t\t}\r\n\r\n\t\t\treturn flights;\r\n\t\t};\r\n\r\n /**\r\n * Returns all the flights from storage\r\n * @memberof FlightFactory\r\n * @returns {Array} flights\r\n */\r\n\t\tfunction getFlightsFromStorage() {\r\n\t\t\tvar objects = localStorageMD5Service.get(objType);\r\n\t\t\treturn fromObjectList(objects);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Returns the flights from local storage only if they are recent\r\n\t\t* @memberof FlightFactory\r\n\t\t* @returns {Array} flights\r\n\t\t*/\r\n\t\tfunction getFlightsFromStorageAndCheckIfTooOld() {\r\n\t\t\tvar result = getFlightsFromStorage();\r\n\r\n\t\t\tif (result == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\tvar dataIsRecent = false;\r\n\t\t\tvar arrayLength = result.length;\r\n\r\n\t\t\t// loop all flights and break if a flight in the last 10 days is found\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (Date.today().add(daysThatAFlightIsConsideredTooOld).days().toUTC().isBefore(new Date(result[i].ScheduledDeparture).toUTC().trimTime())) {\r\n\t\t\t\t\tdataIsRecent = true;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (dataIsRecent == true || (!liveVersion))\r\n\t\t\t\treturn result;\r\n\t\t\telse\r\n\t\t\t\treturn null;\r\n\t\t}\r\n\r\n /**\r\n * Set flights to storage\r\n * @memberof FlightFactory\r\n * @returns {Array} flights\r\n */\r\n\t\tfunction setFlightsToStorage(flights) {\r\n\t\t\tfor (var i = 0; i < flights.length; i++) {\r\n\t\t\t\tif (flights[i].FlightId == undefined || flights[i].FlightId == null) {\r\n\t\t\t\t\tflights[i].FlightId = guid();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tlocalStorageMD5Service.set('flights', flights);\r\n\t\t}\r\n\r\n /**\r\n * Initialize flights and save them\r\n * @memberof FlightFactory\r\n */\r\n\t\tfunction initializeFlights() {\r\n\t\t\tvar objList = localStorageMD5Service.get(objType);\r\n\t\t\tif (objList == null) return null;\r\n\r\n\t\t\tvar arrayLength = objList.length;\r\n\t\t\tvar flights = new Array();\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tvar flight = new Flight();\r\n\t\t\t\tangular.extend(flight, objList[i]);\r\n\r\n\t\t\t\tif (objList[i].crew == null)\r\n\t\t\t\t\tobjList[i].crew = [];\r\n\r\n\t\t\t\tflight.crew = new Array();\r\n\t\t\t\tfor (var j = 0; j < objList[i].crew.length; j++) {\r\n\t\t\t\t\tflight.crew.push(FlightCrewMemberFactory.fromObject(objList[i].crew[j]));\r\n\t\t\t\t}\r\n\r\n\t\t\t\tflight.initialize();\r\n\t\t\t\tflights.push(flight);\r\n\t\t\t}\r\n\r\n\r\n\t\t\tlocalStorageMD5Service.set('flights', flights);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Store Flights With Reports And Messages\r\n\t\t* @memberof FlightFactory\r\n\t\t* @param {Array} flights \r\n\t\t* @param {Array} cabinReports\r\n\t\t* @param {Array} messages\r\n\t\t*/\r\n\t\tfunction storeFlightsWithReportsAndMessages(flights, cabinReports, messages) {\r\n\r\n\t\t\tvar flightsX = fromObjectList(flights);\r\n\t\t\tvar cabinReportsX = ServerCabinReportFactory.fromObjectList(cabinReports);\r\n\t\t\tvar messagesX = MessageFactory.fromObjectList(messages);\r\n\r\n\t\t\tif (flightsX && flightsX instanceof Array && flightsX.length > 0 && (cabinReportsX || messagesX)) {\r\n\r\n\t\t\t\t// loop all flights\r\n\t\t\t\tvar user = UserFactory.getUser();\r\n\t\t\t\tvar f, pr, me;\r\n\t\t\t\tfor (var fi = 0; fi < flightsX.length; fi++) {\r\n\r\n\t\t\t\t\tf = flightsX[fi];\r\n\r\n\t\t\t\t\t// find cabin reports for this flight\r\n\t\t\t\t\tf.cabinReports = [];\r\n\t\t\t\t\tf.messages = [];\r\n\r\n\t\t\t\t\tif (cabinReportsX && cabinReportsX instanceof Array && cabinReportsX.length > 0) {\r\n\r\n\t\t\t\t\t\tfor (var pri = 0; pri < cabinReportsX.length; pri++) {\r\n\r\n\t\t\t\t\t\t\tpr = cabinReportsX[pri];\r\n\t\t\t\t\t\t\tif (pr.FlightId != null && pr.FlightId == f.FlightId) {\r\n\r\n\t\t\t\t\t\t\t\tif (pr.AuthorAimsId == f.CrewAimsId) {\r\n\t\t\t\t\t\t\t\t\tpr.Source = ServerCabinReportFactory.constSourceStoredOwn;\r\n\t\t\t\t\t\t\t\t\tf.cabinReports.push(pr);\r\n\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\tpr.Source = ServerCabinReportFactory.constSourceStoredOther;\r\n\t\t\t\t\t\t\t\t\tf.cabinReports.push(pr);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (messagesX && messagesX instanceof Array && messagesX.length > 0) {\r\n\r\n\t\t\t\t\t\tfor (var mi = 0; mi < messagesX.length; mi++) {\r\n me = messagesX[mi];\r\n var vf = moment.utc(me.ValidFrom);\r\n var vt = moment.utc(me.ValidTo);\r\n if(moment.utc(f.FlightDate).isBetween(vf,vt,undefined,'[]')){\r\n if (me.QueryType.trim() == 'Country' && (me.Country.trim() == f.ArrivalCountry || me.Country.trim() == f.DepartureCountry)) {\r\n f.messages.push(me.Id);\r\n } else if (me.QueryType.trim() == 'FlightNo' && me.FlightNo == f.FlightNo) {\r\n f.messages.push(me.Id);\r\n } else if (me.QueryType.trim() == 'Airports') {\r\n if (me.FlightDirection == 'DEP' && me.AirportA == f.Departure && me.AirportB == f.Arrival) {\r\n f.messages.push(me.Id);\r\n } else if (me.FlightDirection == 'ARR' && me.AirportB == f.Departure && me.AirportA == f.Arrival) {\r\n f.messages.push(me.Id);\r\n } else if (me.FlightDirection == 'ANY' && ((me.AirportA == f.Departure && me.AirportB == f.Arrival) || (me.AirportB == f.Departure && me.AirportA == f.Arrival))) {\r\n f.messages.push(me.Id);\r\n }\r\n\r\n } else if (me.QueryType.trim() == 'Airport') {\r\n if (me.FlightDirection == 'DEP' && me.AirportA == f.Departure) {\r\n f.messages.push(me.Id);\r\n } else if (me.FlightDirection == 'ARR' && me.AirportA == f.Arrival) {\r\n f.messages.push(me.Id);\r\n } else if (me.FlightDirection == 'ANY' && ((me.AirportA == f.Departure) || (me.AirportA == f.Arrival))) {\r\n f.messages.push(me.Id);\r\n }\r\n } else if (me.QueryType.trim() == 'Registration' && f.AcTailNo == me.Registration) {\r\n f.messages.push(me.Id);\r\n } else if (me.QueryType.trim() == 'AcType' && f.AcType == me.AcType) {\r\n f.messages.push(me.Id);\r\n }\r\n }\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tf.initialize();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tlocalStorageMD5Service.set('flights', flightsX);\r\n\t\t}\r\n\r\n /**\r\n * Get Flight from local and storage flights\r\n * @memberof FlightFactory\r\n * @param {number} flightId \r\n * @return {object} flight\r\n */\r\n\t\tfunction getFlightFromTotalFlights(flightId) {\r\n\t\t\tvar flight = getFlightFromStorage(flightId);\r\n\r\n\t\t\tif (!flight) {\r\n\t\t\t\tflight = getLocalFlightFromStorage(flightId);\r\n\t\t\t}\r\n\r\n\t\t\treturn flight;\r\n\t\t}\r\n\r\n /**\r\n * Get Flight from storage flights\r\n * @memberof FlightFactory\r\n * @param {number} flightId \r\n * @return {object} flight\r\n */\r\n\t\tfunction getFlightFromStorage(flightId) {\r\n\t\t\tvar objects = localStorageMD5Service.get(objType);\r\n\t\t\tif (objects == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\tvar result = null;\r\n\r\n\t\t\tvar arrayLength = objects.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (objects[i].FlightId == flightId) {\r\n\t\t\t\t\tresult = objects[i];\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn fromObject(result);\r\n\t\t}\r\n\r\n /**\r\n * Get the Flights of the selected route\r\n * @memberof FlightFactory\r\n * @param {string} Route \r\n * @param {string} DutyDate \r\n * @return {array} flights\r\n */\r\n\t\tfunction getFlightsByRoute(Route, DutyDate) {\r\n\t\t\tvar flights = getFlightsFromStorage();\r\n\t\t\tif (flights == null)\r\n\t\t\t\treturn [];\r\n\r\n\t\t\tvar result = [];\r\n\r\n\t\t\tvar arrayLength = flights.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (flights[i].Route == Route && flights[i].DutyDate == DutyDate) {\r\n\t\t\t\t\tresult.push(flights[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* create a local flight (Add flight button on main screen)\r\n\t\t* @memberof FlightFactory\r\n\t\t* @param {string} datetime \r\n\t\t* @param {string} number \r\n\t\t* @param {string} departure \r\n\t\t* @param {string} destination \r\n\t\t* @param {string} regno \r\n\t\t* @param {string} actype \r\n\t\t* @return {object} flight\r\n\t\t*/\r\n\t\tfunction createLocalFlight(datetime, number, departure, destination, regno, actype) {\r\n\r\n\t\t\tvar user = UserFactory.getUser();\r\n\r\n\t\t\tif (user == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\tvar result = new Flight();\r\n\t\t\tresult.AcTailNo = regno;\r\n\t\t\tresult.AcType = actype;\r\n\t\t\tresult.Category = '-';\r\n\t\t\tresult.CrewAimsId = user.aimsId;\r\n\t\t\tresult.Departure = departure;\r\n\t\t\tresult.Arrival = destination;\r\n\t\t\tresult.FlightAimsId = guid();\r\n\t\t\tresult.FlightId = guid();\r\n\t\t\tresult.FlightDate = datetime.toString('yyyy-MM-dd') + 'T' + datetime.toString('HH:mm:ss');;\r\n\t\t\tresult.FlightNo = number;\r\n\t\t\tresult.IsDHC = 0;\r\n\t\t\tresult.Position = user.position;\r\n\t\t\tresult.ScheduledDeparture = datetime.toString('yyyy-MM-dd') + 'T' + datetime.toString('HH:mm:ss');\r\n\t\t\tresult.Status = 'OK';\r\n\t\t\tresult.IsLocal = true;\r\n\t\t\tresult.initialize();\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Save a local flight\r\n * @memberof FlightFactory\r\n * @param {object} flight\r\n */\r\n\t\tfunction saveLocalFlight(flight) {\r\n\r\n\t\t\t// get the local flights array from storage\r\n\t\t\tvar localFlights = fromObjectList(localStorageMD5Service.get('localFlights'));\r\n\t\t\tif (localFlights == null)\r\n\t\t\t\tlocalFlights = new Array();\r\n\r\n\t\t\t// find the current flight in the array (if present)\r\n\t\t\tvar arrayLength = localFlights.length;\r\n\t\t\tvar flightIndex = -1;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (localFlights[i].FlightId != null && localFlights[i].FlightId == flight.FlightId) {\r\n\t\t\t\t\tflightIndex = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// add or update a copy of the current report\r\n\t\t\tif (flightIndex >= 0)\r\n\t\t\t\tlocalFlights[flightIndex] = flight;\r\n\t\t\telse\r\n\t\t\t\tlocalFlights.push(flight);\r\n\r\n\t\t\t// save\r\n\t\t\tlocalStorageMD5Service.set('localFlights', localFlights);\r\n\t\t}\r\n\r\n /**\r\n * merges the given flights with the stored local flights\r\n * @memberof FlightFactory\r\n * @param {array} serverFlights \r\n * @return {array} flights\r\n */\r\n\t\tfunction getLocalFlightsAndMergeWithServerFlights(serverFlights) {\r\n\r\n\t\t\tif (serverFlights == null)\r\n\t\t\t\tserverFlights = [];\r\n\r\n\t\t\t// get the local flights array from storage\r\n\t\t\tvar localFlights = fromObjectList(localStorageMD5Service.get('localFlights'));\r\n\t\t\tif (localFlights == null)\r\n\t\t\t\tlocalFlights = [];\r\n\r\n\t\t\t// add the local flight to the given array\r\n\t\t\tvar arrayLength = localFlights.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tlocalFlights[i].initialize();\r\n\t\t\t\tserverFlights.push(localFlights[i]);\r\n\t\t\t}\r\n\r\n\r\n\t\t\treturn serverFlights;\r\n\t\t}\r\n /**\r\n * Get Flight from local flights\r\n * @memberof FlightFactory\r\n * @param {number} flightId \r\n * @return {object} flight\r\n */\r\n\t\tfunction getLocalFlightFromStorage(flightId) {\r\n\t\t\tvar flight = GenericService.get(flightId, 'localFlights', objCallback);\r\n\t\t\tif (flight) {\r\n\t\t\t\tflight.initialize();\r\n\t\t\t}\r\n\t\t\treturn fromObject(flight);\r\n\t\t}\r\n /**\r\n * Update Flight from report\r\n * @memberof FlightFactory\r\n * @param {object} report \r\n */\r\n\t\tfunction updateFlightFromReport(report) {\r\n\t\t\tvar flight = getFlightFromStorage(report.FlightId);\r\n\t\t\tif (flight != null && flight != undefined) {\r\n\t\t\t\tvar reportIndex;\r\n\t\t\t\tflight.AcTailNo = report.AcTailNo;\r\n\t\t\t\tflight.AcType = report.AcType;\r\n\r\n\t\t\t\tvar allflights = getFlightsFromStorage();\r\n\t\t\t\tfor (var i = 0; i < allflights.length; i++) {\r\n\t\t\t\t\tif (allflights[i].FlightId != null && allflights[i].FlightId == report.FlightId) {\r\n\t\t\t\t\t\treportIndex = i;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tflight.initialize();\r\n\t\t\t\tallflights[reportIndex] = flight;\r\n\t\t\t\tsetFlightsToStorage(allflights);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\r\n /**\r\n * Update Flight \r\n * @memberof FlightFactory\r\n * @param {object} flight \r\n */\r\n\t\tfunction updateFlight(flight) {\r\n\r\n\t\t\t// get the flights array from storage\r\n\t\t\tvar flights = getFlightsFromStorage();\r\n\r\n\t\t\t// find the current flight in the array (if present)\r\n\t\t\tvar arrayLength = flights.length;\r\n\t\t\tvar flightIndex = -1;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (flights[i].FlightId != null && flights[i].FlightId == flight.FlightId) {\r\n\t\t\t\t\tflightIndex = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t//Add or update a copy of the current report\r\n\t\t\tif (flightIndex >= 0)\r\n\t\t\t\tflights[flightIndex] = flight;\r\n\t\t\telse\r\n\t\t\t\tflights.push(flight);\r\n\r\n\t\t\t//Save\r\n\t\t\tlocalStorageMD5Service.set('flights', flights);\r\n\t\t}\r\n\r\n /**\r\n * mark Schedule Changed Flights by comparing flights from new and old data\r\n * @memberof FlightFactory\r\n * @param {object} newFlights \r\n * @param {object} oldFlights\r\n * @return {object} newFlights \r\n */\r\n\t\tfunction markScheduleChangedFlights(newFlights, oldFlights) {\r\n\t\t\tvar lastScheduleDate = SyncLogFactory.getLastScheduleDate();\r\n\r\n\t\t\t//if there are no old flights or no last schedule date\r\n\t\t\tif (oldFlights && lastScheduleDate) {\r\n\t\t\t\t//loop all new flights\r\n\t\t\t\tvar exists;\r\n\t\t\t\tfor (var i = 0; i < newFlights.length; i++) {\r\n\t\t\t\t\t//loop all old flights\r\n\t\t\t\t\texists = false;\r\n\t\t\t\t\tfor (var j = 0; j < oldFlights.length; j++) {\r\n\t\t\t\t\t\tif (newFlights[i].FlightNo == oldFlights[j].FlightNo && newFlights[i].FlightNo == oldFlights[j].FlightNo && newFlights[i].FlightDate == oldFlights[j].FlightDate && newFlights[i].Departure == oldFlights[j].Departure) {\r\n\t\t\t\t\t\t\texists = true;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t//check if flight is newly added and is before the last schedule date\r\n\t\t\t\t\tvar flightDate = new Date(newFlights[i].FlightDate);\r\n\t\t\t\t\tif (!exists && flightDate.getTime() <= lastScheduleDate) {\r\n\t\t\t\t\t\tnewFlights[i].IsScheduleChanged = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn newFlights;\r\n\t\t}\r\n\r\n\t\t//factory functions\r\n /**\r\n * Update Passenger information\r\n * @memberof FlightFactory\r\n * @param {object} flightInfo The flight informations \r\n */\r\n\t\tfunction mergeFlightInfo(flightInfo, showPaxNames) {\r\n\t\t\tif (flightInfo) {\r\n\t\t\t\tvar currentFlightInfo = GenericService.get(flightInfo.FlightId, objType, objCallback);\r\n\r\n\t\t\t\tcurrentFlightInfo.CrewAimsId = flightInfo.CrewAimsId;\r\n\t\t\t\tcurrentFlightInfo.DutyDate = flightInfo.DutyDate;\r\n\t\t\t\tcurrentFlightInfo.Route = flightInfo.Route;\r\n\t\t\t\tcurrentFlightInfo.FlightId = flightInfo.FlightId;\r\n\t\t\t\tcurrentFlightInfo.FlightAimsId = flightInfo.FlightAimsId;\r\n\t\t\t\tcurrentFlightInfo.FlightDate = flightInfo.FlightDate;\r\n\t\t\t\tcurrentFlightInfo.FlightNo = flightInfo.FlightNo;\r\n\t\t\t\tcurrentFlightInfo.Departure = flightInfo.Departure;\r\n\t\t\t\tcurrentFlightInfo.Arrival = flightInfo.Arrival;\r\n\t\t\t\tcurrentFlightInfo.AcType = flightInfo.AcType;\r\n\t\t\t\tcurrentFlightInfo.AcTailNo = flightInfo.AcTailNo;\r\n\t\t\t\tcurrentFlightInfo.ScheduledDeparture = flightInfo.ScheduledDeparture;\r\n\t\t\t\tcurrentFlightInfo.ScheduledArrival = flightInfo.ScheduledArrival;\r\n\t\t\t\tcurrentFlightInfo.BookedC = flightInfo.BookedC;\r\n\t\t\t\tcurrentFlightInfo.BookedY = flightInfo.BookedY;\r\n\t\t\t\tcurrentFlightInfo.BookedInf = flightInfo.BookedInf;\r\n\t\t\t\tcurrentFlightInfo.BookedPad = flightInfo.BookedPad;\r\n\t\t\t\tcurrentFlightInfo.BookedChld = flightInfo.BookedChld;\r\n\t\t\t\tcurrentFlightInfo.ActualC = flightInfo.ActualC;\r\n\t\t\t\tcurrentFlightInfo.ActualY = flightInfo.ActualY;\r\n\t\t\t\tcurrentFlightInfo.ActualInf = flightInfo.ActualInf;\r\n\t\t\t\tcurrentFlightInfo.ActualPad = flightInfo.ActualPad;\r\n\t\t\t\tcurrentFlightInfo.ActualChld = flightInfo.ActualChld;\r\n\t\t\t\tcurrentFlightInfo.Category = flightInfo.Category;\r\n\t\t\t\tcurrentFlightInfo.Status = flightInfo.Status;\r\n\t\t\t\tcurrentFlightInfo.Position = flightInfo.Position;\r\n\t\t\t\tcurrentFlightInfo.IsDHC = flightInfo.IsDHC;\r\n\t\t\t\tcurrentFlightInfo.CallSign = flightInfo.CallSign;\r\n\t\t\t\tcurrentFlightInfo.DepartureGate = flightInfo.DepartureGate;\r\n\t\t\t\tcurrentFlightInfo.DepartureStand = flightInfo.DepartureStand;\r\n currentFlightInfo.ArrivalStand = flightInfo.ArrivalStand;\r\n\t\t\t\tcurrentFlightInfo.DepartureICAO = flightInfo.DepartureICAO;\r\n\t\t\t\tcurrentFlightInfo.DepartureName = flightInfo.DepartureName;\r\n\t\t\t\tcurrentFlightInfo.DepartureCountry = flightInfo.DepartureCountry;\r\n\t\t\t\tcurrentFlightInfo.ArrivalICAO = flightInfo.ArrivalICAO;\r\n\t\t\t\tcurrentFlightInfo.ArrivalName = flightInfo.ArrivalName;\r\n\t\t\t\tcurrentFlightInfo.ArrivalCountry = flightInfo.ArrivalCountry;\r\n\t\t\t\tcurrentFlightInfo.DepartureTimezone = flightInfo.DepartureTimezone;\r\n\t\t\t\tcurrentFlightInfo.ArrivalTimezone = flightInfo.ArrivalTimezone;\r\n\t\t\t\tcurrentFlightInfo.DepartureSchengen = flightInfo.DepartureSchengen;\r\n\t\t\t\tcurrentFlightInfo.ArrivalSchengen = flightInfo.ArrivalSchengen;\r\n\t\t\t\tcurrentFlightInfo.DepartureEU = flightInfo.DepartureEU;\r\n\t\t\t\tcurrentFlightInfo.ArrivalEU = flightInfo.ArrivalEU;\r\n\t\t\t\tcurrentFlightInfo.ETD = flightInfo.ETD;\r\n\t\t\t\tcurrentFlightInfo.ATD = flightInfo.ATD;\r\n\t\t\t\tcurrentFlightInfo.ETA = flightInfo.ETA;\r\n\t\t\t\tcurrentFlightInfo.ATA = flightInfo.ATA;\r\n\t\t\t\tcurrentFlightInfo.CTOT = flightInfo.CTOT;\r\n\t\t\t\tcurrentFlightInfo.DepartureCountryISO = flightInfo.DepartureCountryISO;\r\n\t\t\t\tcurrentFlightInfo.ArrivalCountryISO = flightInfo.ArrivalCountryISO;\r\n\t\t\t\tcurrentFlightInfo.crew = flightInfo.crew;\r\n\t\t\t\tcurrentFlightInfo.Zones = flightInfo.Zones;\r\n\t\t\t\tcurrentFlightInfo.showPaxNames = showPaxNames;\r\n\r\n\t\t\t\tGenericService.save(currentFlightInfo,objType,objCallback);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n * Get Flights of a Crew Route\r\n * @memberof FlightFactory\r\n * @param {number} dutyNo \r\n * @param {string} dutyDay\r\n\t\t * @return {array} flights\r\n */\r\n\t\tfunction getFlightsByDutyNo(dutyNo, dutyDay){\r\n\t\t\tvar flights = getFlightsFromStorage();\r\n\t\t\tif (flights == null)\r\n\t\t\t\treturn [];\r\n\t\t\tvar result = [];\r\n\t\t\tvar arrayLength = flights.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (flights[i].DutyNo == dutyNo && flights[i].DutyDay == dutyDay) {\r\n\t\t\t\t\tresult.push(flights[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\t\t/**\r\n * Get Flights of a Crew Route using a flightId\r\n * @memberof FlightFactory\r\n * @param {number} flightId \r\n\t\t * @return {array} flights\r\n */\r\n function getFlightsByFlightId(flightId){\r\n var result = [];\r\n var flight = getFlightFromStorage(flightId);\r\n var flights = getFlightsFromStorage();\r\n if (flight != null){\r\n for (var i = 0; i < flights.length; i++) {\r\n if (flights[i].DutyNo == flight.DutyNo && flights[i].DutyDay == flight.DutyDay) {\r\n result.push(flights[i]);\r\n }\r\n }\r\n }\r\n return result;\r\n }\r\n\r\n\t\t\r\n\t\t\r\n\t\t/**\r\n * Get Flights with report status \"Stored\"\r\n * @memberof FlightFactory\r\n\t\t * @return {array} flights\r\n */\r\n\t\tfunction getFlightsWithStoredReport(){\r\n\t\t\tvar flights = getFlightsFromStorage();\r\n\t\t\tif (flights == null)\r\n\t\t\t\treturn [];\r\n\t\t\tvar result = [];\r\n\t\t\tvar arrayLength = flights.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (flights[i].cabinReportStatusDescr == \"Stored\") {\r\n\t\t\t\t\tresult.push(flights[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\t\tfunction getTheFirstAndTheLastFlightDates(){\r\n\t\t\tconst flights = getFlightsFromStorage();\r\n\r\n\t\t\tconst parseDate = dateString => new Date(dateString);\r\n\r\n\t\t\tlet firstFlightDate = null;\r\n\t\t\tlet lastFlightDate = null;\r\n\r\n\t\t\tfor (const obj of flights) {\r\n\t\t\t\t//const currentDate = new Date(obj.FlightDate);\r\n\t\t\t\tconst currentDate = parseDate(obj.FlightDate);\r\n\r\n\t\t\t\tif (!firstFlightDate || currentDate < firstFlightDate) {\r\n\t\t\t\t\tfirstFlightDate = currentDate;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!lastFlightDate || currentDate > lastFlightDate) {\r\n\t\t\t\t\tlastFlightDate = currentDate;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn {firstDate: firstFlightDate, lastDate: lastFlightDate };\r\n\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('ReminderModalCtrl', ReminderModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ReminderModalCtrl\r\n * @description \r\n * Warning Modal about acknowledge schedule changes and medical & passport expiries\r\n * @ngInject\r\n */\r\n function ReminderModalCtrl(showExpiriesReminder, showSubmissionDeadlineReminder, showScheduleChangesReminder, ExpiriesFactory, RequestFactory, ScheduleAcknowledgeFactory, $scope, $uibModalInstance) {\r\n\r\n $scope.cancel = cancel;\r\n //from parent view:\r\n $scope.showScheduleChangesReminder = showScheduleChangesReminder;\r\n $scope.showExpiriesReminder = showExpiriesReminder;\r\n $scope.showSubmissionDeadlineReminder = showSubmissionDeadlineReminder;\r\n $scope.expiryList = ExpiriesFactory.getCrewExpiriesFromStorage();\r\n $scope.submissionDeadline = RequestFactory.getSubmissionDeadlineDateFromStorage();\r\n $scope.daysDiff = daysDiff;\r\n\r\n /**\r\n * Calculates days left\r\n * @return {string} usage\r\n */\r\n function daysDiff(date) {\r\n var today = moment().startOf('day');\r\n var expiryDate = moment(date)\r\n\r\n return expiryDate.diff(today, 'days');\r\n }\r\n\r\n /**\r\n * Closes modal\r\n * @memberof ProposalInfoModalCtr\r\n */\r\n function cancel() {\r\n if ($scope.showScheduleChangesReminder) {\r\n ScheduleAcknowledgeFactory.updateShowScheduleChangesModal(false);\r\n }\r\n if ($scope.showExpiriesReminder) {\r\n ExpiriesFactory.updateShowExpiriesModal(false);\r\n }\r\n if ($scope.showSubmissionDeadlineReminder) {\r\n RequestFactory.updateShowSubmissionDeadlineModal(false);\r\n }\r\n\r\n $uibModalInstance.close('cancel');\r\n }\r\n }\r\n\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.controller('EventFormModalCtrl', EventFormModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name EventFormModalCtrl\r\n * @description \r\n * Flight Fervice Event Form Modal\r\n * @ngInject\r\n */\r\n\tfunction EventFormModalCtrl($scope, eventType, $uibModalInstance, FlightServiceEventsFactory) {\r\n\t\t\r\n\t\t$scope.eventType = { ...JSON.parse(JSON.stringify(eventType)) }\r\n\t\tvar defaultStart = $scope.eventType.event.StartTime ? moment($scope.eventType.event.StartTime) : null;\r\n\t\tvar defaultEnd = $scope.eventType.event.EndTime ? moment($scope.eventType.event.EndTime) : null;\r\n\t\t$scope.cancel = cancel;\r\n\t\t$scope.close = close;\r\n\t\t$scope.submit = submit;\r\n\t\t$scope.startGetTime = startGetTime;\r\n\t\t$scope.endGetTime = endGetTime;\r\n\t\t$scope.resetStart = resetStart;\r\n\t\t$scope.resetEnd = resetEnd;\r\n\t\t$scope.clearRemarks = clearRemarks;\r\n\t\t$scope.requiredValueChanged = requiredValueChanged;\r\n\t\t$scope.showStart = defaultStart != null;\r\n\t\t$scope.showEnd = defaultEnd != null;\r\n\t\t$scope.showStartToggle = showStartToggle;\r\n\t\t$scope.showEndToggle = showEndToggle;\r\n\t\t$scope.showContent = 'eventForm';\r\n\t\t$scope.resultMessage = \"\";\r\n\t\t\r\n\t\t$scope.formValues = {};\r\n\t\t$scope.formValues.StartTime = $scope.eventType.event.StartTime ? moment($scope.eventType.event.StartTime) : null;\r\n\t\t$scope.formValues.EndTime = $scope.eventType.event.EndTime ? moment($scope.eventType.event.EndTime) : null;\r\n\t\t$scope.formValues.notRequired = $scope.eventType.event.NotRequired;\r\n\t\t$scope.formValues.showTimePickers = !$scope.formValues.notRequired;\r\n\r\n\t\tfunction startGetTime() {\r\n\t\t\t$scope.formValues.StartTime = getNowValue();\r\n\t\t}\r\n\t\tfunction endGetTime() {\r\n\t\t\t$scope.formValues.EndTime = getNowValue();\r\n\t\t}\r\n\r\n\t\tfunction resetStart(){\r\n\t\t\t$scope.formValues.StartTime = defaultStart;\r\n\t\t}\r\n\t\tfunction resetEnd(){\r\n\t\t\t$scope.formValues.EndTime = defaultEnd;\r\n\t\t}\r\n\r\n\t\tfunction clearRemarks() {\r\n\t\t\t$scope.eventType.event.Remarks = '';\r\n\t\t}\r\n\r\n\t\tfunction showStartToggle(){\r\n\t\t\t$scope.showStart = !$scope.showStart;\r\n\t\t\tif( !$scope.showStart){\r\n\t\t\t\tresetStart();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction showEndToggle(){\r\n\t\t\t$scope.showEnd = !$scope.showEnd;\r\n\t\t\tif( !$scope.showEnd){\r\n\t\t\t\tresetEnd();\r\n\t\t\t}else{\r\n\t\t\t\t$scope.showStart = true;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction requiredValueChanged(){\r\n\t\t\t$scope.formValues.notRequired = !$scope.formValues.notRequired; \r\n\t\t\tif($scope.formValues.notRequired){\r\n\t\t\t\t$scope.formValues.showTimePickers = false;\r\n\t\t\t\t$scope.formValues.StartTime = null;\r\n\t\t\t\t$scope.formValues.EndTime = null;\r\n\t\t\t\tclearRemarks();\r\n\t\t\t} else{\r\n\t\t\t\t$scope.formValues.showTimePickers = true;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t}\r\n\r\n\t\tfunction getNowValue(){\r\n\t\t\tlet currentUtcTime = new Date().toUTC();\r\n\t\t\treturn moment.utc(currentUtcTime).format();\r\n\t\t}\r\n\r\n\t\t/**\r\n * Close the modal\r\n */\r\n\t\tfunction cancel() {\r\n\t\t\tvar doRefreshPanel = true;\r\n\t\t\t$uibModalInstance.close(doRefreshPanel);\r\n\t\t}\r\n\t\tfunction close() {\r\n\t\t\tvar doRefreshPanel = true;\r\n\t\t\t$uibModalInstance.close(doRefreshPanel);\r\n\t\t}\r\n\r\n\t\t/**\r\n * Submit event\r\n */\r\n\t\tfunction submit() {\r\n\t\t\t$scope.showContent = \"loading\";\r\n\t\t\t// UpdateTimes\r\n\t\t\t$scope.eventType.event.StartTime = ($scope.formValues.StartTime !== null && $scope.formValues.StartTime !== undefined) ? moment($scope.formValues.StartTime) : null;\r\n\t\t\t$scope.eventType.event.EndTime = ($scope.formValues.EndTime !== null && $scope.formValues.EndTime !== undefined) ? moment($scope.formValues.EndTime) : null;\r\n\t\t\t$scope.eventType.event.NotRequired = $scope.formValues.notRequired;\r\n\r\n\t\t\tFlightServiceEventsFactory.saveEvent($scope.eventType.event)\r\n\t\t\t\t.then(res => handleSaveResponse(res))\r\n\t\t\t\t.catch(res => SaveFailedCallBack(res));\r\n\t\t}\r\n\r\n\t\t/**\r\n * Response success\r\n */\t\r\n\t\tfunction handleSaveResponse(results){\r\n\t\t\tif(results && results.data && results.data.success && results.data.data && results.data.data.length>0){\r\n\t\t\t\tFlightServiceEventsFactory.setEventsForFlightId($scope.eventType.event.FlightId, results.data.data);\r\n\t\t\t\t//Success\r\n\t\t\t\t$scope.resultMessage = \"Success\";\r\n\t\t\t\t$scope.showContent = 'results';\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\t//Failed\r\n\t\t\t\t$scope.resultMessage = \"Failed\";\r\n\t\t\t\t$scope.showContent = 'results';\r\n\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n * Response failed\r\n */\t\r\n\t\tfunction SaveFailedCallBack(){\r\n\t\t\t$scope.resultMessage = \"Failed\";\r\n\t\t\t$scope.showContent = 'results';\r\n\t\t}\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('FlightServiceEventsFactory', FlightServiceEventsFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightServiceEventsFactory\r\n * @description \r\n * Get selected flight info\r\n * @ngInject\r\n */ \r\nfunction FlightServiceEventsFactory($http, apiUrl, GenericService) {\r\n \r\n var service = {\r\n setEventTypes: setEventTypes,\r\n setEventsForFlightId: setEventsForFlightId,\r\n getEventsFromLS: getEventsFromLS,\r\n getEventTypes: getEventTypes,\r\n getEventsByFlightIdFromLS: getEventsByFlightIdFromLS,\r\n getEvents: getEvents,\r\n saveEvent: saveEvent,\r\n cleanOldDataServiceEvents: cleanOldDataServiceEvents,\r\n upsertEvents: upsertEvents\r\n };\r\n\r\n /**\r\n * Initialize the EventType \r\n * @memberof FlightServiceEventsFactory\r\n */\r\n function EventType() {\r\n this.Id = null;\r\n this.Code = null;\r\n this.Title = null;\r\n this.Description = null;\r\n this.EnableStartTime = true;\r\n this.EnableEndTime = false;\r\n this.EnableNotRequired = false;\r\n this.AllowRemarks = false;\r\n }\r\n var objEventType = 'flightEventTypes';\r\n var objEventTypeCallback = EventType;\r\n\r\n /**\r\n * Save Event Types\r\n * @memberof FlightServiceEventsFactory\r\n * @param {Array} EventTypes\r\n */\r\n function setEventTypes(eventTypes) {\r\n GenericService.saveAll(eventTypes, objEventType);\r\n }\r\n\r\n /**\r\n * Get Event Types\r\n * @memberof FlightServiceEventsFactory\r\n * @returns {Array} EventTypes \r\n */\r\n function getEventTypes() {\r\n return GenericService.list(objEventType, objEventTypeCallback);\r\n }\r\n\r\n\r\n /**\r\n * Initialize the Event \r\n * @memberof FlightServiceEventsFactory\r\n */\r\n function Event() {\r\n this.FlightId = null;\r\n this.EventTypeId = null;\r\n this.EventCode = null;\r\n this.StartTime = null;\r\n this.EndTime = null;\r\n this.NotRequired = null;\r\n this.Remarks = null;\r\n this.LastUpdated = null;\r\n }\r\n var objEvent = 'flightEvents';\r\n var objEventCallback = Event;\r\n\r\n\r\n function getEventsFromLS() {\r\n return GenericService.list(objEvent, objEventCallback);\r\n }\r\n\r\n function getEventsByFlightIdFromLS(flightId) {\r\n var storedEvents = getEventsFromLS(); \r\n return storedEvents.filter(x => x.FlightId == flightId);\r\n }\r\n\r\n function upsertEvents(events) {\r\n var flightIds = events.map(x => x.FlightId);\r\n var storedEvents = getEventsFromLS(); \r\n var otherEvents = storedEvents.filter(x => !flightIds.includes(x.FlightId));\r\n var mergeEvents = otherEvents.concat(events);\r\n setEvents(mergeEvents);\r\n }\r\n\r\n function setEventsForFlightId(flightId, events) {\r\n var storedEvents = getEventsFromLS(); \r\n var filterEvents = storedEvents.filter(x => x.FlightId != flightId);\r\n var mergeEvents = filterEvents.concat(events);\r\n setEvents(mergeEvents);\r\n }\r\n\r\n function setEvents(events) {\r\n GenericService.saveAll(events, objEvent);\r\n }\r\n\r\n function getEvents(flightId, callback){\r\n var uri = encodeURI(apiUrl + '/FlightServiceEvents/GetEvents?flightId=' + flightId);\r\n return $http.get(uri, { 'Content-Type': 'application/json' })\r\n .catch(callback); \r\n }\r\n\r\n function saveEvent (event, callback){\r\n var eventTimesFixed = { ...event };\r\n if(event.StartTime){\r\n eventTimesFixed.StartTime = event.StartTime.clone();\r\n var startDateObj = new Date(eventTimesFixed.StartTime).fromUTC();\r\n eventTimesFixed.StartTime = moment(startDateObj);\r\n }else{\r\n eventTimesFixed.StartTime = null;\r\n }\r\n if(event.EndTime){\r\n eventTimesFixed.EndTime = event.EndTime.clone();\r\n var endDateObj = new Date(eventTimesFixed.EndTime).fromUTC();\r\n eventTimesFixed.EndTime = moment(endDateObj);\r\n }else{\r\n eventTimesFixed.EndTime = null;\r\n }\r\n\r\n return $http.post(apiUrl + '/FlightServiceEvents/SaveEvent', eventTimesFixed, { 'Content-Type': 'application/json' })\r\n .catch(callback); \r\n }\r\n\r\n function cleanOldDataServiceEvents(responseFlightIds){ \r\n var storedEvents = getEventsFromLS(); \r\n var previousEvents = storedEvents.filter(x => responseFlightIds.includes(x.FlightId));\r\n setEvents(previousEvents);\r\n }\r\n\r\n return service;\r\n}\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('GroomingCategoriesFactory', GroomingCategoriesFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name GroomingCategoriesFactory\r\n * @description \r\n * Get grooming categories\r\n * @ngInject\r\n */\r\n function GroomingCategoriesFactory($http, apiUrl, GenericService) {\r\n var groomingReportsByCrew = {}; \r\n var service = {\r\n setGroomingCategories: setGroomingCategories,\r\n getGroomingCategories: getGroomingCategories,\r\n collectGroomingReports: collectGroomingReports,\r\n saveGroomingReports: saveGroomingReports,\r\n loadGroomingReports: loadGroomingReports,\r\n clearGroomingReportsFromStorage: clearGroomingReportsFromStorage\r\n };\r\n\r\n /**\r\n * Initialize the GroomingCategory\r\n * @memberof GroomingCategoriesFactory\r\n */\r\n function GroomingCategory() {\r\n this.Id = null;\r\n this.Label = null;\r\n this.Description = null;\r\n this.OrderNo = null;\r\n this.Active = false;\r\n }\r\n var objEventType = 'groomingCategories';\r\n var objCallback = GroomingCategory;\r\n\r\n /**\r\n * Save grooming categories\r\n * @memberof GroomingCategoriesFactory\r\n * @param {Array} GroomingCategories\r\n */\r\n function setGroomingCategories(groomingCategories) {\r\n GenericService.saveAll(groomingCategories, objEventType);\r\n }\r\n\r\n /**\r\n * Get Event Types\r\n * @memberof FlightServiceEventsFactory\r\n * @returns {Array} EventTypes \r\n */\r\n function getGroomingCategories() {\r\n return GenericService.list(objEventType, objCallback);\r\n }\r\n\r\n function collectGroomingReports(groomingReportsByCrew){\r\n var groomingReports = [];\r\n\r\n if(groomingReportsByCrew){\r\n for (var crewId in groomingReportsByCrew){\r\n var crewReports = groomingReportsByCrew[crewId];\r\n crewReports.forEach(category => {\r\n if(category.UserInput && category.UserInput.trim() !== \"\") {\r\n groomingReports.push({\r\n crewId: crewId,\r\n groomingCategoryId: category.Id,\r\n feedback: category.UserInput.trim()\r\n })\r\n }\r\n });\r\n }\r\n }\r\n return groomingReports;\r\n }\r\n\r\n function saveGroomingReports (groomingReports) {\r\n localStorage.setItem('groomingReports', JSON.stringify(groomingReports));\r\n };\r\n \r\n function loadGroomingReports () {\r\n return JSON.parse(localStorage.getItem('groomingReports')) || {};\r\n };\r\n\r\n function clearGroomingReportsFromStorage() {\r\n localStorage.removeItem('groomingReports');\r\n };\r\n \r\n\r\n return service;\r\n }\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.controller('GroomimgCategoriesModalCtrl', GroomimgCategoriesModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name GroomimgCategoriesModalCtrl\r\n * @description \r\n * Grooming Categories Form Modal\r\n * @ngInject\r\n */\r\n\tfunction GroomimgCategoriesModalCtrl($scope, $uibModalInstance, crewData, groomingCategories) {\r\n\t\t$scope.crewData = crewData;\r\n\r\n const originalCategories = angular.copy(groomingCategories); // Deep copy for preservation\r\n $scope.groomingCategories = angular.copy(groomingCategories); // Working copy for the modal\r\n\t\t$scope.close = close;\r\n $scope.save = save;\r\n\r\n $scope.isSaveEnabled = function() {\r\n return $scope.groomingCategories.every(category => {\r\n if (category.isSelected) {\r\n return category.UserInput && category.UserInput.trim() !== '';\r\n }\r\n return true;\r\n });\r\n };\r\n \r\n\r\n $scope.toggleCategorySelection = function(category) {\r\n category.isSelected = !category.isSelected;\r\n \r\n // Clear remarks if the category is unchecked\r\n if (!category.isSelected) {\r\n category.UserInput = \"\"; // Reset the input field\r\n }\r\n };\r\n \r\n // Function to clear specific input\r\n $scope.clearInput = function (category) {\r\n category.UserInput = ''; \r\n };\r\n\r\n // Close the modal\r\n\t\tfunction close() {\r\n $scope.groomingCategories = angular.copy(originalCategories);\r\n $uibModalInstance.dismiss('cancel');\r\n\t\t}\r\n\r\n function save () {\r\n angular.copy($scope.groomingCategories, groomingCategories);\r\n // Close the modal and return the updated grooming categories\r\n $uibModalInstance.close($scope.groomingCategories);\r\n };\r\n\t}\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('gdCrewInfo', gdCrewInfo);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name crewInfo\r\n * @restrict E\r\n * @description\r\n * Crew Table with a double row per crew member\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function gdCrewInfo($uibModal, UserFactory) {\r\n function link(scope) {\r\n scope.user = UserFactory.getUser();\r\n scope.openPhoneConfirmation = openPhoneConfirmation;\r\n scope.showInfoRow = showInfoRow;\r\n\r\n function openPhoneConfirmation(crew) {\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/CrewInfo/dlgConfirmCrewCall.html',\r\n controller: 'CrewCallCtrl',\r\n size: 'md',\r\n resolve: {\r\n crew: function () { return crew; },\r\n groundDutyId: function () { return scope.grounddutyid; },\r\n flightId: function () { return null; }\r\n }\r\n });\r\n modalInstance.result.then(function (confirm) {\r\n\r\n });\r\n }\r\n\r\n function showInfoRow(item) {\r\n var differentUser = scope.user.aimsId != item.AIMS_ID;\r\n var phoneAvailable = item.PhoneNumber && item.PhoneNumber != '';\r\n\r\n return differentUser && phoneAvailable;\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/GroundDuty/gdCrewInfo.tpl.html',\r\n scope: { crew: \"=\", grounddutyid: \"=\" },\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('GroundDutyFactory', GroundDutyFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name GroundDutyFactory\r\n * @description \r\n * Add, Update and Get Ground Duties.\r\n * @ngInject\r\n */\r\n function GroundDutyFactory(GenericService, $http, apiUrl) {\r\n\r\n /**\r\n * Initialize the GroundDuty\r\n * @memberof GroundDutyFactory\r\n */\r\n function GroundDuty() {\r\n this.Id = null;\r\n this.Duty = null;\r\n this.DutyDescription = null;\r\n this.DutyBegin = null;\r\n this.DutyEnd = null;\r\n this.GetId = GetId;\r\n this.isTraining = false;\r\n this.icon = null;\r\n this.Instructors = new Array();\r\n this.Trainees = new Array();\r\n this.isManualEntry = false;\r\n this.hasPendingCourse = false;\r\n }\r\n\r\n var objType = 'groundDuty';\r\n var objCallback = GroundDuty;\r\n\r\n var service = {\r\n getGroundDutiesFromStorage: getGroundDutiesFromStorage,\r\n setGroundDutiesToStorage: setGroundDutiesToStorage,\r\n getGroundDutyFromStorage: getGroundDutyFromStorage,\r\n getGroundDutyActiveCourses: getGroundDutyActiveCourses,\r\n getGroundDutiesByDutyNo: getGroundDutiesByDutyNo,\r\n mergeGroundDutyInfo: mergeGroundDutyInfo,\r\n updateGroundDuty: updateGroundDuty,\r\n setCourseCompleted: setCourseCompleted,\r\n setCoursePending: setCoursePending,\r\n isLastDay: isLastDay,\r\n mergeGroundDutiesToStorage: mergeGroundDutiesToStorage,\r\n refresh: refresh,\r\n addGroundDuty: addGroundDuty,\r\n removeGroundDuty: removeGroundDuty,\r\n getManualGroundDutiesFromStorage: getManualGroundDutiesFromStorage,\r\n getFirstAndLastDateOfGroundDuties: getFirstAndLastDateOfGroundDuties\r\n };\r\n\r\n /**\r\n * Overide default get Id\r\n * @memberof GroundDutyFactory\r\n * @returns {number} Id \r\n */\r\n function GetId() {\r\n return this.Id;\r\n }\r\n\r\n /**\r\n * Get Ground Duties.\r\n * @memberof GroundDutyFactory\r\n * @returns {Array} GroundDuties \r\n */\r\n function getGroundDutiesFromStorage() {\r\n return GenericService.list(objType, objCallback);\r\n }\r\n /**\r\n * Get GroundDuty from storage groundDuties\r\n * @memberof GroundDutyFactory\r\n * @param {number} groundDutyId \r\n * @return {object} groundDuty\r\n */\r\n function getGroundDutyFromStorage(groundDutyId) {\r\n var groundDuty = GenericService.get(groundDutyId, objType, objCallback);\r\n var instructors = [];\r\n var trainees = [];\r\n\r\n if (groundDuty != null && groundDuty != undefined) {\r\n //only training\r\n if (groundDuty.RelatedGroundDuties && groundDuty.RelatedGroundDuties.length > 1) {\r\n groundDuty.isTraining = true;\r\n\r\n groundDuty.RelatedGroundDuties.forEach(function (element) {\r\n if (element.IsInstructor) {\r\n instructors.push(element);\r\n }\r\n else {\r\n trainees.push(element);\r\n }\r\n });\r\n\r\n groundDuty.Trainees = trainees;\r\n groundDuty.Instructors = instructors;\r\n }\r\n }\r\n return groundDuty;\r\n }\r\n /**\r\n * Save Ground Duties to storage\r\n * @memberof GroundDutyFactory\r\n * @param {Array} GroundDuties A list of Ground Duties\r\n */\r\n function setGroundDutiesToStorage(objList) {\r\n GenericService.saveAll(objList, objType);\r\n }\r\n\r\n /**Save Ground Duties to storage but keep local storage values\r\n * Necessary to maintain Absent values in training duties\r\n */\r\n function mergeGroundDutiesToStorage(objList, fromSync) {\r\n var groundDuties = getGroundDutiesFromStorage();\r\n\r\n if(!fromSync) {\r\n groundDuties.filter(x => x.isManualEntry).forEach(function (duty) {\r\n objList.push(duty);\r\n }); \r\n }\r\n \r\n if (groundDuties) {\r\n objList.forEach(function (incomingDuty) {\r\n\r\n if (incomingDuty.RelatedGroundDuties) {\r\n var incomingTraineesFlat = [];\r\n incomingDuty.RelatedGroundDuties.filter(x => !x.IsInstructor).forEach(function (related) {\r\n related.CrewMembers.forEach(function (trainee) {\r\n incomingTraineesFlat.push(trainee);\r\n });\r\n });\r\n\r\n //Initialize all as present\r\n incomingTraineesFlat.forEach(function (incomingTrainee) {\r\n incomingTrainee.Absent = false;\r\n });\r\n\r\n //Copy Absent value from existing local storage duties\r\n var existingDuty = groundDuties.find(x => x.Id == incomingDuty.Id);\r\n if (existingDuty && existingDuty.RelatedGroundDuties) {\r\n var existingTraineesFlat = [];\r\n existingDuty.RelatedGroundDuties.filter(x => !x.IsInstructor).forEach(function (related) {\r\n related.CrewMembers.forEach(function (trainee) {\r\n existingTraineesFlat.push(trainee);\r\n });\r\n });\r\n\r\n incomingTraineesFlat.forEach(function (incomingTrainee) {\r\n var existingTrainee = existingTraineesFlat.find(x => x.Id == incomingTrainee.Id);\r\n if (existingTrainee) {\r\n incomingTrainee.Absent = existingTrainee.Absent;\r\n }\r\n });\r\n }\r\n\r\n }\r\n\r\n });\r\n }\r\n GenericService.saveAll(objList, objType);\r\n }\r\n\r\n /**\r\n * Get GroundDuties of a Crew Route\r\n * @memberof GroundDutyFactory \r\n * @param {number} dutyNo \r\n * @param {string} dutyDay\r\n * @return {array} groundDuties\r\n */\r\n function getGroundDutiesByDutyNo(dutyNo, dutyDay) {\r\n var groundDuties = getGroundDutiesFromStorage();\r\n if (groundDuties == null)\r\n return [];\r\n var result = [];\r\n\r\n var instructors = [];\r\n var trainees = [];\r\n\r\n var arrayLength = groundDuties.length;\r\n for (var i = 0; i < arrayLength; i++) {\r\n if (groundDuties[i].DutyNo == dutyNo && groundDuties[i].DutyDay == dutyDay) {\r\n //only training\r\n if (groundDuties[i].RelatedGroundDuties && groundDuties[i].RelatedGroundDuties.length > 1) {\r\n groundDuties[i].isTraining = true;\r\n\r\n instructors = [];\r\n trainees = [];\r\n\r\n groundDuties[i].RelatedGroundDuties.forEach(function (element) {\r\n if (element.IsInstructor) {\r\n instructors.push(element);\r\n }\r\n else {\r\n trainees.push(element);\r\n }\r\n });\r\n\r\n groundDuties[i].Trainees = trainees;\r\n groundDuties[i].Instructors = instructors;\r\n }\r\n\r\n result.push(groundDuties[i]);\r\n }\r\n }\r\n\r\n\r\n return result;\r\n }\r\n\r\n /**\r\n * Merge new info to current Ground Duty\r\n * @memberof GroundDutyFactory\r\n * @param {object} duty \r\n */\r\n function mergeGroundDutyInfo(duty) {\r\n var currentGroundDutyInfo = GenericService.get(duty.Id, objType, objCallback);\r\n currentGroundDutyInfo.Code = duty.Code;\r\n currentGroundDutyInfo.Description = duty.Description;\r\n currentGroundDutyInfo.DutyDate = duty.DutyDate;\r\n currentGroundDutyInfo.GroundDutyNo = duty.GroundDutyNo;\r\n currentGroundDutyInfo.DutyDateS = duty.DutyDateS;\r\n currentGroundDutyInfo.DutyBegin = duty.DutyBegin;\r\n currentGroundDutyInfo.DutyEnd = duty.DutyEnd;\r\n currentGroundDutyInfo.DutyDay = duty.DutyDay;\r\n currentGroundDutyInfo.DutyNo = duty.DutyNo;\r\n currentGroundDutyInfo.Route = duty.Route;\r\n\r\n if (currentGroundDutyInfo.RelatedGroundDuties && currentGroundDutyInfo.RelatedGroundDuties.length) {\r\n currentGroundDutyInfo.RelatedGroundDuties = duty.RelatedGroundDuties;\r\n }\r\n GenericService.save(currentGroundDutyInfo, objType, objCallback);\r\n }\r\n\r\n /**\r\n * Check in calendar if this is the last day of this duty\r\n * @param {object} groundDuty \r\n */\r\n function isLastDay(groundDuty, course) {\r\n //Get duty's Trainee codes\r\n var traineeCodes = [... new Set(groundDuty.RelatedGroundDuties.filter(x => x.Courses && x.Courses.find(y => y.CourseId == course.Id))\r\n .map(r => r.Code))];\r\n\r\n //Get Remaining Trainee codes\r\n var remainingTraineeCodes = [];\r\n var remainingGroundDuties = GenericService.list(objType, objCallback) //get all grounDuties\r\n .filter(x => x.RelatedGroundDuties &&\r\n x.RelatedGroundDuties.length > 1 && //filter only training\r\n dateDifference(groundDuty.DutyBegin, x.DutyBegin) < 0); //check later duty date\r\n\r\n remainingGroundDuties.forEach(function (groundDuty) {\r\n var codes = groundDuty.RelatedGroundDuties.filter(x => !x.IsInstructor).map(y => y.Code); //only trainee codes\r\n remainingTraineeCodes = remainingTraineeCodes.concat(codes);\r\n });\r\n\r\n remainingTraineeCodes = [...new Set(remainingTraineeCodes)]; //remove duplicates\r\n\r\n return !remainingTraineeCodes.some(r => traineeCodes.includes(r));\r\n }\r\n\r\n /**\r\n * Compares two dates\r\n * @param {date} currentDate \r\n * @param {date} checkDate \r\n */\r\n function dateDifference(currentDate, checkDate) {\r\n var currentDate = moment(currentDate);\r\n var checkDate = moment(checkDate);\r\n return currentDate.diff(checkDate)\r\n }\r\n\r\n function updateGroundDuty(groundDuty) {\r\n GenericService.save(groundDuty, objType, objCallback);\r\n }\r\n\r\n\r\n function addGroundDuty(groundDuty) {\r\n var storedGroundDuty = GenericService.get(groundDuty.Id, objType, objCallback);\r\n if (!storedGroundDuty) {\r\n GenericService.add(groundDuty, objType, objCallback);\r\n }\r\n else {\r\n updateGroundDuty(groundDuty);\r\n }\r\n }\r\n\r\n function removeGroundDuty(groundDuty) {\r\n GenericService.remove(groundDuty, objType, objCallback);\r\n }\r\n\r\n function setCourseCompleted(dutyId, courseId) {\r\n var groundDuty = GenericService.get(dutyId, objType, objCallback);\r\n groundDuty.RelatedGroundDuties.filter(x => x.Courses).forEach(function (item) {\r\n var groundDutyCourse = item.Courses.find(x => x.CourseId == courseId);\r\n if (groundDutyCourse) {\r\n groundDutyCourse.Status = \"Completed\";\r\n }\r\n });\r\n\r\n var allCoursesAreCompleted = false;\r\n\r\n if (groundDuty.RelatedGroundDuties && groundDuty.RelatedGroundDuties.length > 0) {\r\n allCoursesAreCompleted = groundDuty.RelatedGroundDuties.filter(x => x.Courses && x.Courses.length > 0).every(function (relatedDuty) {\r\n return relatedDuty.Courses.every(function (course) {\r\n return course.Status == \"Completed\";\r\n });\r\n });\r\n }\r\n\r\n if (groundDuty.isManualEntry && allCoursesAreCompleted) {\r\n groundDuty.hasPendingCourse = false;\r\n }\r\n updateGroundDuty(groundDuty);\r\n }\r\n\r\n function setCoursePending(dutyId, courseId) {\r\n var groundDuty = GenericService.get(dutyId, objType, objCallback);\r\n groundDuty.RelatedGroundDuties.filter(x => x.Courses).forEach(function (item) {\r\n var groundDutyCourse = item.Courses.find(x => x.CourseId == courseId);\r\n if (groundDutyCourse) groundDutyCourse.Status = \"Pending\";\r\n });\r\n updateGroundDuty(groundDuty);\r\n }\r\n\r\n function getGroundDutyActiveCourses(groundDutyId) {\r\n var groundDuty = GenericService.get(groundDutyId, objType, objCallback);\r\n var courses = [];\r\n if (groundDuty != null && groundDuty != undefined) {\r\n if (groundDuty.RelatedGroundDuties && groundDuty.RelatedGroundDuties.length > 1) {\r\n groundDuty.RelatedGroundDuties.filter(x => !x.IsInstructor && x.Courses).forEach(function (item) {\r\n courses.push(...item.Courses);\r\n });\r\n }\r\n }\r\n return courses;\r\n }\r\n\r\n function refresh(refreshGroundDuty, callback) {\r\n return $http.post(apiUrl + '/GroundDuty/Refresh', refreshGroundDuty, { 'Content-Type': 'application/json' })\r\n .then(callback);\r\n }\r\n\r\n /**Get manual Ground Duties from storage*/\r\n function getManualGroundDutiesFromStorage() {\r\n var groundDuties = getGroundDutiesFromStorage();\r\n return groundDuties.filter(x => x.isManualEntry);\r\n }\r\n\r\n function getFirstAndLastDateOfGroundDuties(){\r\n var groundDuties = getGroundDutiesFromStorage();\r\n\r\n\t\t\tconst parseDate = dateString => new Date(dateString);\r\n\r\n\t\t\tlet firstDutyDate = null;\r\n\t\t\tlet lastDutyDate = null;\r\n\r\n\t\t\tfor (const obj of groundDuties) {\r\n\t\t\t\tconst currentDate = parseDate(obj.DutyDate);\r\n\r\n\t\t\t\tif (!firstDutyDate || currentDate < firstDutyDate) {\r\n\t\t\t\t\tfirstDutyDate = currentDate;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (!lastDutyDate || currentDate > lastDutyDate) {\r\n\t\t\t\t\tlastDutyDate = currentDate;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn {firstDate: firstDutyDate, lastDate: lastDutyDate };\r\n\r\n }\r\n\r\n return service;\r\n }\r\n\r\n})();","\r\n(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('SearchPastGDCtrl', SearchPastGDCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SearchPastGDCtrl\r\n * @description \r\n * Search pending duties \r\n * @ngInject\r\n */ \r\nfunction SearchPastGDCtrl($scope, GroundDutyFactory, PastDutyFactory, $uibModalInstance, $route, CourseFactory, defaultCalendarDate, CrewRouteFactory, FlightFactory) {\t\t\t\r\n\t\t$scope.dutyId = null;\r\n\t\t$scope.showContent = 'search';\r\n\t\t$scope.course = {\r\n\t\t\tisCourseLimited : true\r\n\t\t}\r\n\t\t$scope.hasError = false;\r\n\r\n\t\t// cancel\r\n\t\t$scope.doCancel = doCancel;\r\n\r\n\t\t$scope.closeModal = closeModal;\r\n\r\n\t\t$scope.showMessage = true;\r\n\r\n\t\tvar today = new Date().toUTC();\r\n if (defaultCalendarDate) {\r\n today = new Date(defaultCalendarDate).toUTC();\r\n }\r\n\r\n $scope.dutyDatePicker = {\r\n value: today,\r\n format: 'dd-MM-yyyy',\r\n opened: false\r\n }\r\n\t\r\n $scope.dateFormat = 'dd-MM-yyyy';\r\n\r\n $scope.openDatepicker = openDatepicker;\r\n\r\n function openDatepicker() {\r\n $scope.dutyDatePicker.opened = true;\r\n }\r\n\r\n $scope.searchGDByDate = searchGDByDate;\t\r\n $scope.searchNotStarted = searchNotStarted;\t\r\n\r\n function searchGDByDate() {\r\n\t\t\t$scope.hasError = false;\r\n\t\t\t$scope.showContent = 'loading';\r\n\t\t\tPastDutyFactory.getPastDuties($scope.dutyDatePicker.value.toString('yyyy-MM-dd')) \r\n\t\t\t\t.then(res => handleSubmitResponse(res))\r\n .catch(res => handleFailedResponse(res));\r\n\t\t}\r\n\r\n function searchNotStarted() {\r\n\t\t\t$scope.hasError = false;\r\n\t\t\t$scope.showContent = 'loading';\r\n\t\t\tPastDutyFactory.getNotStartedDuties($scope.dutyDatePicker.value.toString('yyyy-MM-dd')) \r\n\t\t\t\t.then(res => handleNotStartedSubmitResponse(res))\r\n .catch(res => handleNotStartedFailedResponse(res));\r\n\t\t}\r\n\r\n\r\n\t\t// search pending gd\r\n\t\t$scope.searchGD = searchGD;\t\r\n\r\n /**\r\n * Close the modal\r\n * @memberof SearchPastGDCtrl\r\n */\r\n function doCancel() {\r\n\t\t\t$uibModalInstance.close('cancel');\r\n\t\t} \r\n\r\n\t\tfunction searchGD() {\t\t\t\r\n\t\t\t$scope.showContent = 'loading';\r\n\t\t\tPastDutyFactory.getPastDuties('') \r\n\t\t\t\t.then(res => handleSubmitResponse(res))\r\n .catch(res => handleFailedResponse(res));\r\n\t\t}\r\n\t\t\t\r\n\t\tfunction handleSubmitResponse(res) {\r\n\t\t\t$scope.showContent = 'results';\r\n\r\n\t\t\t$scope.availableCources = res.data.trainingCourses;\r\n $scope.pendingDuties = res.data.pendingGroundDuties;\r\n $scope.flightTrainings = res.data.pendingRoutes;\r\n $scope.pendingFlightCourses = res.data.flightCourses;\r\n \r\n var flights = res.data.flightsForPendingRoutes;\r\n FlightFactory.insertFlightsWithPendingTrainings(flights);\r\n\r\n $scope.availableCources.forEach(function(course) {\r\n course.HasLimitedInfo = true;\r\n CourseFactory.upsertCourse(course, function() { });\r\n });\r\n $scope.pendingDuties.forEach(function(duty) {\r\n duty.isManualEntry = true;\r\n duty.hasPendingCourse = true;\r\n GroundDutyFactory.addGroundDuty(duty);\r\n });\r\n $scope.flightTrainings.forEach(function(pendingRoute){\r\n pendingRoute.isManualEntry = true;\r\n pendingRoute.hasPendingCourse = true;\r\n CrewRouteFactory.addCrewRouteDuty(pendingRoute);\r\n });\r\n $scope.pendingFlightCourses.forEach(function(course) {\r\n course.HasLimitedInfo = true;\r\n CourseFactory.upsertCourse(course, function() { });\r\n });\r\n }\r\n\r\n function handleNotStartedSubmitResponse(res) {\r\n\t\t\t$scope.showContent = 'notStartedResults';\r\n\r\n\t\t\t$scope.notStartedGroundDuties = res.data.notStartedGroundDuties; \r\n $scope.groundCourses = res.data.trainingCourses;\r\n\r\n $scope.notStartedGroundDuties.forEach(function(duty) {\r\n duty.isManualEntry = true;\r\n duty.hasPendingCourse = true;\r\n GroundDutyFactory.addGroundDuty(duty);\r\n }); \r\n $scope.groundCourses.forEach(function(course) {\r\n course.HasLimitedInfo = true;\r\n CourseFactory.upsertCourse(course, function() { });\r\n }); \r\n }\r\n\r\n\t\tfunction closeModal() {\r\n\t\t\t$uibModalInstance.close();\r\n\t\t\t$route.reload();\r\n\t\t}\r\n\r\n\t\tfunction handleFailedResponse(res) {\r\n $scope.showContent = 'results';\r\n\t\t\t$scope.hasError = true;\r\n }\t\r\n \r\n function handleNotStartedFailedResponse(res) {\r\n $scope.showContent = 'notStartedResults';\r\n\t\t\t$scope.hasError = true;\r\n }\t\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('PastDutyFactory', PastDutyFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PastDutyFactory\r\n * @description \r\n * Get Past Duties.\r\n * @ngInject\r\n */ \r\nfunction PastDutyFactory($http, apiUrl) {\r\n\r\n var service = {\r\n getPastDuties: getPastDuties,\r\n getNotStartedDuties: getNotStartedDuties\r\n };\r\n\r\n function getPastDuties(selectedDate, callback) {\r\n return $http.get(apiUrl + '/Training/GetPastDuties?specificDutyDate=' + selectedDate, { 'Content-Type': 'application/json' })\r\n .catch(callback); \r\n } \r\n \r\n function getNotStartedDuties(selectedDate, callback) {\r\n return $http.get(apiUrl + '/Training/GetNotStartedDuties?specificDutyDate=' + selectedDate, { 'Content-Type': 'application/json' })\r\n .catch(callback); \r\n } \r\n return service;\r\n}\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.config(compileProviderConfig);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc config\r\n * @name compileProviderConfig\r\n * @description \r\n * Config aHref Sanitization Whitelist (make \"safe\" to download image from data url)\r\n * @ngInject\r\n */\r\nfunction compileProviderConfig($compileProvider) {\r\n $compileProvider.aHrefSanitizationWhitelist(/^\\s*(https?|ftp|mailto|file|ghttps?|ms-appx|x-wmapp0|data|tel):/);\r\n}\r\n \r\n})();\r\n\r\n","(function() {\r\n 'use strict';\r\n \r\n// By default, AngularJS will catch errors and log them to\r\n// the Console. We want to keep that behavior; however, we\r\n// want to intercept it so that we can also log the errors\r\n// to the server for later analysis.\r\na3_cabin_reports.config(exceptionConfig);\r\n\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc config\r\n * @name exceptionConfig\r\n * @description \r\n * By default, AngularJS will catch errors and log them to\r\n * the Console. We want to keep that behavior; however, we\r\n * want to intercept it so that we can also log the errors\r\n * to the server for later analysis.\r\n * @ngInject\r\n */\r\nfunction exceptionConfig($provide) {\r\n $provide.decorator('$exceptionHandler', extendExceptionHandler);\r\n}\r\n\r\n /**\r\n * @memberof exceptionConfig\r\n * @description \r\n * Override default exception handling and log errors \r\n * @ngInject\r\n */\t\r\nfunction extendExceptionHandler($delegate, LogService) {\r\n return function(exception, cause) {\r\n $delegate(exception, cause);\r\n /**\r\n * Could add the error to a service's collection,\r\n * add errors to $rootScope, log errors to remote web server,\r\n * or log locally. Or throw hard. It is entirely up to you.\r\n * throw exception;\r\n */\r\n LogService.error(exception, cause);\r\n };\r\n}\r\n \r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.factory('httpCrewTokenInterceptor', httpCrewTokenInterceptor);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name httpCrewTokenInterceptor\r\n * @description \r\n * Add CrewToken on non login requests\r\n * @ngInject\r\n */\r\nfunction httpCrewTokenInterceptor($location, localStorageMD5Service,UserTokenFactory) {\r\n\t\treturn {\r\n\t\t\trequest: function(config) {\r\n if ($location.$$url != \"/login\") {\r\n\r\n\t\t\t\t\t// get the user token\r\n\t\t\t\t\tvar user = localStorageMD5Service.get('user');\r\n\t\t\t\t\tvar token = '';\r\n\t\t\t\t\tif (user != null)\r\n\t\t\t\t\t\ttoken = user.token;\r\n\r\n\t\t\t\t\tconfig.headers['X-CrewToken'] = token;\r\n\t\t\t\t}\r\n\t\t\t\treturn config;\r\n\t\t\t},\r\n response: function (response) {\r\n if(response.headers()['content-type'] === \"application/json; charset=utf-8\"){\r\n \r\n var expiresAt = response.headers()['x-expires-token']\r\n var crewToken = response.headers()['x-rolling-token']\r\n\r\n if(expiresAt && crewToken ){\r\n var user = localStorageMD5Service.get('user');\r\n if (user != null){\r\n user.token = crewToken;\r\n user.expires = expiresAt;\r\n localStorageMD5Service.set('user',user);\r\n }\r\n UserTokenFactory.setToken(crewToken);\r\n\r\n }\r\n }\r\n return response;\r\n }\r\n\r\n\t\t};\r\n\t}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('httpHeaderInterceptor', httpHeaderInterceptor);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name httpHeaderInterceptor\r\n * @description \r\n * Add CrewToken on non login requests\r\n * @ngInject\r\n */\r\n function httpHeaderInterceptor($location, localStorageMD5Service) {\r\n return {\r\n request: function (config) {\r\n if ($location.$$url != \"/login\") {\r\n if (config.url.includes(\"api\")) {\r\n var user = localStorageMD5Service.get('user');\r\n var aimsIdToString = user.aimsId.toString();\r\n if (config.method === \"POST\" || config.method === \"PUT\") {\r\n var dataToHash = typeof config.data === \"object\" ? angular.toJson(config.data) + aimsIdToString : config.data + aimsIdToString;\r\n var hash = (dataToHash).getHash();\r\n config.headers['X-VCode'] = hash;\r\n }\r\n else if (config.method === \"GET\") {\r\n var absolutePath = config.url;\r\n var stringToHash = absolutePath.substring(absolutePath.lastIndexOf(\"/\") + 1, absolutePath.length);\r\n var hash = (stringToHash + aimsIdToString).getHash();\r\n config.headers['X-VCode'] = hash;\r\n }\r\n }\r\n\r\n }\r\n return config;\r\n }\r\n };\r\n }\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\n\r\na3_cabin_reports.config(httpProviderConfig)\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc config\r\n * @name httpProviderConfig\r\n * @description \r\n * Register interceptors and modify headers\r\n * @ngInject\r\n */\r\nfunction httpProviderConfig($httpProvider) {\r\n\t$httpProvider.defaults.useXDomain = true;\r\n\tdelete $httpProvider.defaults.headers.common['X-Requested-With'];\r\n\r\n\t$httpProvider.interceptors.push('http401interceptor');\r\n $httpProvider.interceptors.push('httpCrewTokenInterceptor');\r\n $httpProvider.interceptors.push('httpHeaderInterceptor');\r\n}\r\n\r\n \r\n})();","(function() {\r\n 'use strict';\r\n \r\n\r\na3_cabin_reports.config(localStorageMD5Config)\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc config\r\n * @name localStorageMD5Config\r\n * @description \r\n * Config localStorageMD5ServiceProvider directly by using localStorageMD5ServiceProvider\r\n * @ngInject\r\n */\r\nfunction localStorageMD5Config(localStorageMD5ServiceProvider, localStorageServiceProvider) {\r\n //localStorageMD5ServiceProvider.help();\r\n var regx = /[?&]secure[&#]?/;\r\n if (regx.exec(window.location.href)) {\r\n console.log('*** SECURE MODE ***');\r\n localStorageServiceProvider.setStorageType('sessionStorage');\r\n }\r\n localStorageServiceProvider.setPrefix('a3.cabin.reports');\r\n localStorageServiceProvider.setStorageCookie(10, '/');\r\n localStorageMD5ServiceProvider.enableCompression();\r\n}\r\n \r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory(\"LogService\",LogService);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name LogService\r\n * @description \r\n * The error log service is our wrapper around the core error\r\n * handling ability of AngularJS. Notice that we pass off to\r\n * the native \"$log\" method and then handle our additional\r\n * server-side logging.\r\n * @ngInject\r\n */\r\n function LogService($log, $injector, $window, apiUrl, version, UserTokenFactory) {\r\n var lastError = null;\r\n //define how many seconds to wait before resending the same error (to avoid multiple errors for the same prob)\r\n var acceptedTimeDiff = 5;\r\n function post(errorMessage, stackTrace, cause) {\r\n\r\n\r\n\t\t\ttry {\r\n\t\t\t\tvar $http = $injector.get(\"$http\");\r\n\t\t\t\t/*// get the user token\r\n\t\t\t\tvar user = UserFactory.getUser();\r\n\t\t\t\tvar token = '';\r\n\t\t\t\tif (user != null)\r\n\t\t\t\t\ttoken = user.token;*/\r\n\t\t\t\tvar token = UserTokenFactory.getToken();\r\n\t\t\t\t// Log the JavaScript error to the server.\r\n\t\t\t\t// --\r\n\t\t\t\t// NOTE: In this demo, the POST URL doesn't\r\n\t\t\t\t// exists and will simply return a 404.\r\n\r\n\t\t\t\t$http({\r\n\t\t\t\t\tmethod: \"POST\",\r\n\t\t\t\t\turl: apiUrl + \"/log\",\r\n\t\t\t\t\tcontentType: \"application/json\",\r\n\t\t\t\t\tdata: {\r\n\t\t\t\t\t\terrorUrl: $window.location.href,\r\n\t\t\t\t\t\terrorMessage: version + \" \" + errorMessage,\r\n\t\t\t\t\t\tstackTrace: stackTrace,\r\n\t\t\t\t\t\tcause: (cause || \"\")\r\n\t\t\t\t\t},\r\n\t\t\t\t\tbeforeSend: function(request) {\r\n\t\t\t\t\t\trequest.setRequestHeader('X-CrewToken', token);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t\t} catch (loggingError) {\r\n\r\n\t\t\t\t// For Developers - log the log-failure.\r\n\t\t\t\t$log.warn(\"Error logging failed\");\r\n\t\t\t\t$log.log(loggingError);\r\n\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\tfunction postFilter(errorMessage, stackTrace, cause) {\r\n\t\t\tif (lastError != null && lastError.errorDescr == errorMessage) {\r\n\t\t\t\tvar timestampDiff = Date.now() - lastError.timestamp;\r\n\t\t\t\tvar timeDiffInSec = timestampDiff / 1000;\r\n\t\t\t\tif (timeDiffInSec > acceptedTimeDiff) {\r\n\t\t\t\t\tlastError = {\r\n\t\t\t\t\t\t'errorDescr': errorMessage,\r\n\t\t\t\t\t\t'timestamp': Date.now()\r\n\t\t\t\t\t};\r\n\t\t\t\t\tpost(errorMessage, stackTrace, cause);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tlastError = {\r\n\t\t\t\t\t'errorDescr': errorMessage,\r\n\t\t\t\t\t'timestamp': Date.now()\r\n\t\t\t\t};\r\n\t\t\t\tpost(errorMessage, stackTrace, cause);\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\treturn {\r\n\t\t\tdebug: function(errorMessage, error) {\r\n\t\t\t\tif (error == null) {\r\n\t\t\t\t\terror = new Error();\r\n\t\t\t\t}\r\n\t\t\t\tif (errorMessage != null) {\r\n\t\t\t\t\terror.description = errorMessage;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tpost(error.description, error.stack, \"\");\r\n\r\n\t\t\t},\r\n\t\t\terror: function(exception, cause) {\r\n\r\n\t\t\t\t// Pass off the error to the default error handler\r\n\t\t\t\t// on the AngualrJS logger. This will output the\r\n\t\t\t\t// error to the console (and let the application\r\n\t\t\t\t// keep running normally for the user).\r\n\t\t\t\t$log.error.apply($log, arguments);\r\n\r\n\t\t\t\t// Now, we need to try and log the error the server.\r\n\t\t\t\t// --\r\n\t\t\t\t// NOTE: In production, I have some debouncing\r\n\t\t\t\t// logic here to prevent the same client from\r\n\t\t\t\t// logging the same error over and over again! All\r\n\t\t\t\t// that would do is add noise to the log.\r\n\t\t\t\tvar errorMessage = exception.toString();\r\n\t\t\t\t//var stackTrace = stacktraceService.print({ e: exception });\r\n\t\t\t\t//var stackTrace = $log.info({ e: exception });\r\n\t\t\t\tvar stackTrace = exception.stack;\r\n\t\t\t\tpostFilter(errorMessage, stackTrace, cause);\r\n\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t}\r\n \r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.factory('UserTokenFactory', UserTokenFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name UserTokenFactory\r\n * @description \r\n * Used to maintain the user token, outside the localStorage, in order to be accessible from the service which logs js errors\r\n * /(this service may not use localstorage provider)\r\n * @ngInject\r\n */\r\nfunction UserTokenFactory() {\r\n\t\treturn {\r\n\t\t\t token: '',\r\n \r\n\t\t\tsetToken: function(value) {\r\n\t\t\t\tthis.token = value;\r\n\t\t\t},\r\n\r\n\t\t\tgetToken: function() {\r\n\t\t\t\treturn this.token;\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('annualLeavesSummary', annualLeavesSummary);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name annualLeavesSummary\r\n * @restrict E\r\n * @description\r\n * Implementation of annual Leaves Summary\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function annualLeavesSummary(AnnualLeavesFactory) {\r\n function link($scope, element, attrs) {\r\n $scope.showAnnualLeavesSummary = false;\r\n\r\n var annualLeavesInfo = AnnualLeavesFactory.getAnnualLeavesToStorage();\r\n if (annualLeavesInfo && annualLeavesInfo.length > 0){\r\n $scope.showAnnualLeavesSummary = true;\r\n $scope.annualLeaves = groupAnnualLeavesByType(annualLeavesInfo);\r\n } \r\n\r\n function groupAnnualLeavesByType(annualLeavesInfo) {\r\n var groupedLeaves = [];\r\n annualLeavesInfo = annualLeavesInfo.sort(function (a, b) {\r\n return b.Date < a.Date ? 1: -1 \r\n });\r\n \r\n for (var i = 0; i < annualLeavesInfo.length; i++) {\r\n var previousGroup = groupedLeaves[groupedLeaves.length - 1];\r\n if (i != 0 && previousGroup.type == annualLeavesInfo[i].Type && (new Date(annualLeavesInfo[i].Date) - new Date(previousGroup.dates[previousGroup.dates.length - 1]) === 86400000)) {\r\n previousGroup.dates.push(annualLeavesInfo[i].Date);\r\n }\r\n else {\r\n var item = { type: annualLeavesInfo[i].Type, dates: [] };\r\n item.dates.push(annualLeavesInfo[i].Date);\r\n groupedLeaves.push(item);\r\n }\r\n }\r\n return groupedLeaves;\r\n }\r\n\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/LeaveRequest/annual-leaves-summary.tpl.html',\r\n scope: true,\r\n link: link\r\n }\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n a3_cabin_reports.factory('AnnualLeavesFactory', AnnualLeavesFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AnnualLeavesFactory\r\n * @description \r\n * Get Annual Leaves Data \r\n * @ngInject\r\n */\r\n function AnnualLeavesFactory(GenericService, $http, apiUrl) {\r\n\r\n /**\r\n * Initialize the AnnualLeaves\r\n * @memberof CheckInFactory\r\n */\r\n function AnnualLeaves() {\r\n\r\n }\r\n\r\n var objType = 'AnnualLeaves';\r\n var objCallback = AnnualLeaves;\r\n\r\n var service = {\r\n setAnnualLeavesToStorage: setAnnualLeavesToStorage,\r\n getAnnualLeavesToStorage: getAnnualLeavesToStorage\r\n }\r\n \r\n /**\r\n * Save Annual Leaves\r\n * @param {array} annualLeavesInInfo \r\n */\r\n function setAnnualLeavesToStorage(annualLeavesInInfo) {\r\n if (annualLeavesInInfo == undefined || annualLeavesInInfo == null) {\r\n GenericService.removeAll(objType);\r\n }\r\n else { \r\n GenericService.saveAll(annualLeavesInInfo, objType, objCallback);\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Gets annual leaves\r\n * @returns {annualLeavesObj} annualLeavesObj\r\n */\r\n /**\r\n * Get annual leaves\r\n */\r\n function getAnnualLeavesToStorage() {\r\n return GenericService.list(objType, objCallback);;\r\n }\r\n\r\n return service;\r\n }\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('flexCombination',FlexCombination);\r\n\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name FlexCombination\r\n * @restrict E\r\n * @description\r\n * Implementation of Flex Combinations\r\n *\r\n * Initialize the Flex Combination of a season\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */ \r\nfunction FlexCombination($timeout) {\r\n \r\n function link(scope, element, attrs){\r\n \r\n \r\n angular.forEach(scope.seasonRequest.LeaveRequestPriorityPeriods, function (value, key) {\r\n var temp = value.MockLeaveRequestPrioritySlots;\r\n var temp2 = value.LeaveRequestPrioritySlots;\r\n\r\n $timeout(function(){\r\n value.MockLeaveRequestPrioritySlots = angular.fromJson(temp);\r\n value.LeaveRequestPrioritySlots= angular.fromJson(temp2);\r\n }) \r\n \r\n });\r\n \r\n scope.sortableOptions = {\r\n handle: '>.row .myHandle',\r\n update: function(e, ui) {\r\n },\r\n stop: function(e, ui) {\r\n for(var i=0; i< scope.seasonRequest.LeaveRequestPriorityPeriods.length;i++){ \r\n sortSetupOrderNo(scope.seasonRequest.LeaveRequestPriorityPeriods[i])\r\n }\r\n }\r\n }; \r\n \r\n \r\n \r\n scope.setupOrderNo = setupOrderNo;\r\n \r\n function sortSetupOrderNo(period){\r\n if(Array.isArray(period.LeaveRequestPrioritySlots)){\r\n for (var i=0; i0;\r\n \r\n for(var i=0;iSuccess
\",\r\n message :\"You have successfully submitted your leave request. You can modify your leave request untill the \" + closeDateStr + \".\",\r\n callback: function(){ $route.reload(); }\r\n });\r\n }\r\n \r\n function ShowErrorMessage(){\r\n bootbox.alert({title : \"
Error
\",\r\n message :\"Failed to send your leave request. Please try again later\",\r\n callback: function(){ $route.reload(); }\r\n });\r\n }\r\n \r\n function progressBarBox( isOpen ){\r\n if(isOpen){\r\n bootbox.dialog({\r\n closeButton: false,\r\n message: '
Please wait...
',\r\n //title: \"Please wait...\"\r\n });\r\n }else {\r\n bootbox.hideAll();\r\n }\r\n\r\n }\r\n \r\n/* function setupView() {\r\n if (!UserFactory.isLoggedIn()) {\r\n $location.path(\"/login\");\r\n }*/\r\n \r\n //$scope.sortableOptions['ui-floating'] = true;\r\n \r\n function updateLeaveRequestSeason(season){\r\n season.ConfigurationId = season.Configuration.Id\r\n for(var i=0;i $scope.LeaveRequestInformation.LeaveDays){\r\n $scope.invalidSelectedLeaveDays = true;\r\n bootbox.alert((\"

Warning!

You are entilted to \" + $scope.LeaveRequestInformation.LeaveDays + \" leave days but you have selected a combination of \" + totalDays + \" days. Please proceed with the necessary changes.\") \r\n\t\t\t\t);\r\n \r\n } else if (!$scope.QualificationGroup.RequestLessDays && (totalDays < $scope.LeaveRequestInformation.LeaveDays)){\r\n $scope.invalidSelectedLeaveDays = true; \r\n if(hasConfig){\r\n bootbox.alert((\"

Warning!

You are entilted to \" + $scope.LeaveRequestInformation.LeaveDays + \" leave days but you have selected a combination of \" + totalDays + \" days. Please proceed with the necessary changes.\") \r\n\t\t\t\t );\r\n }\r\n }\r\n else{\r\n $scope.invalidSelectedLeaveDays = false;\r\n }\r\n }\r\n \r\n function getRandomBorderColor(season){\r\n var cssClass = \"border-left-green\"\r\n \r\n if(!season.Configuration){\r\n cssClass = \"border-left-orange\";\r\n }\r\n \r\n return cssClass;\r\n }\r\n \r\n function getRandomTextColor(season){\r\n var cssClass = \"text-green\"\r\n \r\n if(!season.Configuration){\r\n cssClass = \"text-orange\";\r\n }\r\n return cssClass;\r\n }\r\n \r\n }\r\n})();","(function () {\r\n 'use strict';\r\n a3_cabin_reports.factory('LeaveRequestFactory', LeaveRequestFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name LeaveRequestFactory\r\n * @description \r\n * Get Leave Request Configuration Data and submit new Leave Request\r\n * @ngInject\r\n */\r\n function LeaveRequestFactory(GenericService, $http, $q, apiUrl) {\r\n\r\n \r\n var service = {\r\n getConfigurationDetails : getConfigurationDetails,\r\n saveLeaveRequestInformation : saveLeaveRequestInformation,\r\n getLeaveRequestInformation : getLeaveRequestInformation,\r\n saveLeaveRequest : saveLeaveRequest\r\n };\r\n \r\n /**\r\n * Initialize the LeaveRequestInformation\r\n * @memberof LeaveRequestFactory\r\n */\r\n function LeaveRequestInformation(){\r\n \r\n }\r\n \r\n var objType = 'LeaveRequestInformation';\r\n\t\tvar objCallback = LeaveRequestInformation; \r\n \r\n var leaveRequestApiURL = apiUrl + '/LeaveRequest';\r\n \r\n \r\n /**\r\n * Get the LeaveRequestInformation and the qualification Group\r\n * @memberof LeaveRequestFactory\r\n * @param {function} callback an on success callback function\r\n * @param {function} errorCallback an on error callback function\r\n */\r\n function getConfigurationDetails(callback,errorCallback) {\r\n return $http.get(leaveRequestApiURL, { 'Content-Type': 'application/json' })\r\n .then(function(responseData){\r\n if(responseData && responseData.data && responseData.data.data && responseData.data.data.LeaveRequestInformation){\r\n saveLeaveRequestInformation(responseData.data.data.LeaveRequestInformation);\r\n }\r\n callback(responseData);\r\n })\r\n .catch(errorCallback);\r\n }\r\n \r\n function saveLeaveRequest(request,callback,errorCallback){\r\n var cleanRequest = angular.toJson(request);\r\n return $http.post(leaveRequestApiURL,cleanRequest ,{ 'Content-Type': 'application/json' })\r\n .then(function(responseData){\r\n if(responseData && responseData.data && responseData.data.data && responseData.data.data.LeaveRequestInformation){\r\n saveLeaveRequestInformation(responseData.data.data.LeaveRequestInformation);\r\n }\r\n callback(responseData);\r\n })\r\n .catch(errorCallback);\r\n }\r\n /**\r\n * Save the leave Request Information Object in local storage\r\n * @memberof LeaveRequestFactory\r\n * @param {object} leaveRequestInformation a leaveRequestInformation\r\n */\r\n function saveLeaveRequestInformation(leaveRequestInformation){\r\n GenericService.saveOne(leaveRequestInformation,objType,objCallback);\r\n }\r\n \t\r\n /**\r\n * Save the leave Request Information Object in local storage\r\n * @memberof LeaveRequestFactory \r\n * @returns {object} leaveRequestInformation \r\n */\r\n function getLeaveRequestInformation(){\r\n return GenericService.getOne(objType,objCallback);\r\n }\r\n\r\n /*function postProposal(proposal){\r\n return $http.post(apiUrl + '/bucket/PostProposal/', proposal, { 'Content-Type' : 'application/json' });\r\n }\r\n */\r\n\r\n return service;\r\n }\r\n\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\n a3_cabin_reports.controller('LeaveRequestInstructionsCtrl',LeaveRequestInstructionsCtrl);\r\n\r\n /**\r\n * @memberof PilotReports\r\n * @ngdoc controller\r\n * @name LeaveRequestInstructionsCtrl\r\n * @description \r\n * Get the Leave Request Instructions\r\n * @ngInject\r\n */\r\nfunction LeaveRequestInstructionsCtrl($scope, $uibModalInstance){\r\n\t\t$scope.page = 1;\r\n\t\t$scope.cancel = cancel;\r\n $scope.nextPage = nextPage;\r\n $scope.previousPage = previousPage;\r\n \r\n $scope.instructionPages = 3;\r\n \r\n /**\r\n * Goes to the next page of leave instructions\r\n * @memberof LeaveRequestInstructionsCtrl\r\n */\r\n function nextPage(){\r\n $scope.page = $scope.page + 1;\r\n normalizePage();\r\n }\r\n \r\n /**\r\n * Goes to the previous page of leave instructions\r\n * @memberof LeaveRequestInstructionsCtrl\r\n */\r\n function previousPage(){\r\n $scope.page = $scope.page - 1;\r\n normalizePage();\r\n }\r\n \r\n /**\r\n * Normalize the page number if it is out of range\r\n * @memberof LeaveRequestInstructionsCtrl\r\n */\r\n function normalizePage(){\r\n if($scope.page > $scope.instructionPages || $scope.page<1){\r\n $scope.page = 1;\r\n }\r\n }\r\n /**\r\n * Close the modal\r\n * @memberof LeaveRequestInstructionsCtrl\r\n */\r\n\t\tfunction cancel() {\r\n\t\t\t$uibModalInstance.close('close');\r\n\t\t};\r\n\t\t\r\n\t}\r\n })(); ","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('specificCombinations',SpecificCombinations);\r\n\r\n \r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name SpecificCombinations\r\n * @restrict E\r\n * @description\r\n * Implementation of Specific Combinations\r\n *\r\n * Initialize the Specific Combinations of a season\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */ \r\nfunction SpecificCombinations($filter) {\r\n \r\n function link(scope, element, attrs){\r\n scope.IsEditEnabled = false;\r\n scope.selectEditablePeriod = selectEditablePeriod;\r\n scope.updateEditablePeriod = updateEditablePeriod;\r\n scope.removeSpecificCombination = removeSpecificCombination;\r\n scope.addNewSpecificCombination = addNewSpecificCombination;\r\n scope.getBorderClass = getBorderClass;\r\n scope.selectedSlotTemp = null;\r\n scope.isDisabled = isDisabled;\r\n \r\n scope.specificCombinations = $filter('filter')(scope.seasonRequests, {Type: 'All'});\r\n \r\n scope.sortableOptions = {\r\n handle: '> .row .myHandle',\r\n update: function(e, ui) {\r\n \r\n },\r\n stop: function(e, ui) {\r\n recalculatePriorities();\r\n }\r\n };\r\n \r\n \r\n \r\n function recalculatePriorities(){\r\n for(var i=0;i0){\r\n scope.selectedSlotTemp = period.LeaveRequestPrioritySlots[0];\r\n }else {\r\n scope.selectedSlotTemp = null;\r\n }\r\n scope.selectedRequestTemp = request;\r\n scope.selectedSlotDaysTemp = period.Days;\r\n period.isEditable = true;\r\n scope.IsEditEnabled = true;\r\n }else{\r\n resetEditablePeriods();\r\n }\r\n }\r\n \r\n function getBorderClass(request){\r\n var hasEmptyFields = false;\r\n var hasFilledFields = false;\r\n var cssClass= \"\";\r\n for (var i=0; i< request.LeaveRequestPriorityPeriods.length;i++){\r\n hasEmptyFields = hasEmptyFields || (!request.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots || request.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots.length==0);\r\n hasFilledFields = hasFilledFields || !(!request.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots || request.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots.length==0);\r\n \r\n }\r\n \r\n if(hasEmptyFields && hasFilledFields ){\r\n cssClass = 'specific-combination-orange'\r\n request.HasInvalidPeriod = true;\r\n }else if(hasEmptyFields && !hasFilledFields){\r\n cssClass ='specific-combination-blue'\r\n request.HasInvalidPeriod = false;\r\n }else if (hasFilledFields && !hasEmptyFields){\r\n cssClass ='specific-combination-green'\r\n request.HasInvalidPeriod = false;\r\n }\r\n \r\n return cssClass;\r\n }\r\n \r\n function isDisabled(slot){\r\n var CSSclass=\"\";\r\n if(scope.selectedRequestTemp){\r\n for (var i=0; i< scope.selectedRequestTemp.LeaveRequestPriorityPeriods.length;i++){\r\n if( scope.selectedRequestTemp.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots && \r\n scope.selectedRequestTemp.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots.length>0 && (scope.selectedRequestTemp.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots[0].Id == slot.Id || \r\n (scope.selectedRequestTemp.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots[0].EndDay >=slot.StartDay &&\r\n scope.selectedRequestTemp.LeaveRequestPriorityPeriods[i].LeaveRequestPrioritySlots[0].StartDay <= slot.EndDay\r\n ) )\r\n ){\r\n CSSclass=\"disabled\";\r\n break;\r\n }\r\n }\r\n \r\n }\r\n \r\n return CSSclass;\r\n \r\n }\r\n \r\n \r\n function resetEditablePeriods(){\r\n for(var i=0;i 0){\r\n newSpecificCombinationPriority = scope.specificCombinations.length + 1;\r\n }\r\n var newObj= { Type : \"All\",\r\n Priority: newSpecificCombinationPriority,\r\n LeaveRequestPriorityPeriods : []\r\n }\r\n \r\n scope.seasonRequests.push(newObj);\r\n \r\n updateLeaveRequestSeason();\r\n \r\n scope.specificCombinations = $filter('filter')(scope.seasonRequests, {Type: 'All'});\r\n scope.IsEditEnabled = false;\r\n \r\n }\r\n \r\n function updateLeaveRequestSeason(){\r\n scope.seasonConfiguration.ConfigurationId = scope.seasonConfiguration.Configuration.Id\r\n for(var i=0;i 3){\r\n\t\t\t\tlocalStorageMD5Service.remove('failedLoginAttemps');\r\n\t\t\t\tresetUser();\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\t$scope.isLoggingIn = true;\r\n\t\t\t\tUserFactory.azlogin(afterLoginSuccess, afterLoginError, afterLoginFinal)\r\n\t\t\t\t.catch(error => {\r\n\t\t\t\t\t//console.error(\"An error occurred during login:\", error);\r\n\t\t\t\t\tafterLoginError();\r\n\t\t\t\t});\r\n\r\n\t\t\t}\r\n\t\t}\r\n\r\n /**\r\n * AfterLoginSuccess\r\n * @memberof LoginCtrl\r\n */\r\n function afterLoginSuccess() {\r\n $scope.isLoggingIn = false;\r\n // load main page\r\n $scope.errorName = \"\";\r\n $location.path(\"/\");\r\n }\r\n\r\n /**\r\n * afterLoginFinal\r\n * @memberof LoginCtrl\r\n */\r\n\t\tfunction afterLoginFinal() {\r\n\t\t\t$scope.isLoggingIn = false;\r\n\t\t}\r\n\r\n\t\t/**\r\n * AfterLoginError\r\n * @memberof LoginCtrl\r\n */\r\n\t\tfunction afterLoginError(response) {\r\n\t\t\t$scope.isLoggingIn = false;\r\n\r\n\t\t\t// display an error message\r\n\t\t\tif (response && response.status == 401) {\r\n\t\t\t\tif (response.data && response.data.Message)\r\n\t\t\t\t\t$scope.errorName = response.data.Message.length > 1 ? response.data.Message : \"You are not authorized to use this CLS Cabin app\";\r\n\t\t\t\telse\r\n\t\t\t\t\t$scope.errorName = \"You are not authorized to use this CLS Cabin app\";\r\n\t\t\t} else if (response && response.status == 404) {\r\n\t\t\t\t$scope.errorName = \"Could not reach the remote server for authentication. Please connect to the Internet and try again.\";\r\n\t\t\t} else {\r\n\t\t\t\t$scope.errorName = \"An error occured during authentication. Please make sure you are connected to the Internet and try again.\";\r\n\t\t\t};\r\n\t\t}\r\n\r\n\r\n\t\t/**\r\n * Redirect to reset view\r\n * @memberof LoginCtrl\r\n */\r\n\t\tfunction resetDevice() {\r\n\t\t\t$location.path(\"/reset\");\r\n\t\t}\r\n\t\t/**\r\n * Sign out\r\n * @memberof LoginCtrl\r\n */\r\n\t\tfunction resetUser(){\r\n\t\t\tUserFactory.azSignOut();\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.factory('UserFactory', UserFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name UserFactory\r\n * @description \r\n * Add, Update, Delete and Get User.\r\n * @ngInject\r\n */\r\n\t//function UserFactory(localStorageMD5Service, CabinAPIService, DataCleanerFactory, GenericService, LogService, $http, apiUrl) {\r\n\tfunction UserFactory(LogService, localStorageMD5Service, $http, apiUrl, CabinAPIService, DataCleanerFactory, GenericService,azureADAuth) {\r\n \r\n\t\tvar msalConfig = {\r\n auth: azureADAuth,\r\n cache: {\r\n cacheLocation: \"sessionStorage\", // This configures where your cache will be stored\r\n storeAuthStateInCookie: false, // Set this to \"true\" if you are having issues on IE11 or Edge\r\n\t\t\t\t\r\n }\r\n };\r\n var myMSALObj = new msal.PublicClientApplication(msalConfig);\r\n var username = null;\r\n\r\n\r\n myMSALObj.handleRedirectPromise()\r\n .then(handleResponse)\r\n .catch((error) => {\r\n console.error(error);\r\n\t\t \tLogService.error(error, 'Failed to handle redirect Login');\r\n });\r\n\r\n function handleResponse(response) {\r\n\t\t\t\r\n if (response !== null) {\r\n username = response.account.username;\r\n } else {\r\n selectAccount();\r\n\r\n }\r\n }\r\n\r\n function selectAccount () {\r\n /**\r\n * See here for more info on account retrieval: \r\n * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-common/docs/Accounts.md\r\n */\r\n const currentAccounts = myMSALObj.getAllAccounts();\r\n \r\n if (currentAccounts.length === 0) {\r\n return;\r\n } else if (currentAccounts.length > 0) {\r\n username = currentAccounts[0].username;\r\n }\r\n }\r\n \r\n\t\t/**\r\n * Initialize the User\r\n * @memberof UserFactory\r\n */\r\n\t\tfunction User() {\r\n\t\t\tthis.id = null;\r\n\t\t\tthis.aimsId = null;\r\n\t\t\tthis.name = null;\r\n\t\t\tthis.shortname = null;\r\n\t\t\tthis.position = null;\r\n\t\t\tthis.hashedPwd = null;\r\n\t\t\tthis.token = null;\r\n\t\t\tthis.syncDialogLastDt = null;\r\n\t\t\tthis.getDescription = getDescription;\r\n\t\t\tthis.tokenExtended = false;\r\n\t\t}\r\n\r\n\t\tvar service =\r\n\t\t{\r\n\t\t\tgetUser: getUser,\r\n\t\t\tsetUser: setUser,\r\n\t\t\tisSecure: isSecure,\r\n\t\t\tisLoggedIn: isLoggedIn,\r\n\t\t\tclearActiveUser: clearActiveUser,\r\n\t\t\tsetActiveUser: setActiveUser,\r\n\t\t\tlogin: login,\r\n\t\t\textendToken: extendToken,\r\n azlogin: azlogin,\r\n azSignOut:azSignOut,\r\n\t\t\tgetLoginFailedAttemps: getLoginFailedAttemps,\r\n\t\t\tnewLoginFailedAttemp: newLoginFailedAttemp\r\n\t\t};\r\n\r\n\t\tvar objType = 'user';\r\n\t\tvar objCallback = User;\r\n\r\n\t\t//Object Functions\r\n\t\tfunction getDescription() {\r\n\t\t\tif (this.aimsid == null && this.name == null) return '-null-';\r\n\t\t\telse return (this.aimsid || '?') + ' - ' + (this.name || '?');\r\n\t\t}\r\n\r\n\t\t//Factory Functions\r\n /**\r\n * Get User \r\n * @memberof UserFactory\r\n * @returns {Object} User\r\n */\r\n\t\tfunction getUser() {\r\n\t\t\treturn GenericService.getOne(objType, objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Save User \r\n\t\t* @memberof UserFactory\r\n\t\t* @param {Object} User\r\n\t\t*/\r\n\t\tfunction setUser(user) {\r\n\t\t\tGenericService.saveAll(user, objType, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Checks if local storage is on secure mode \r\n * @memberof UserFactory\r\n * @param {boolean} isSecure\r\n */\r\n\t\tfunction isSecure() {\r\n\t\t\treturn localStorageMD5Service.isSecure();\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Check if user exists and he has logged in\r\n\t\t* @memberof UserFactory\r\n\t\t* @param {boolean} isLoggedIn\r\n\t\t*/\r\n\t\tfunction isLoggedIn() {\r\n\t\t\tvar user = null;\r\n\t\t\ttry {\r\n\t\t\t\tuser = getUser();\r\n\t\t\t\tif (user != null) {\r\n\t\t\t\t\tvar act = localStorageMD5Service.get('active');\r\n\t\t\t\t\tif (!act || !act.aimsId || act.aimsId != user.aimsId) {\r\n\t\t\t\t\t\tuser = null;\r\n\t\t\t\t\t}\r\n\t\t\t\t} else\r\n\t\t\t\t\tuser = null;\r\n\t\t\t} catch (e) {\r\n\t\t\t\tuser = null;\r\n\t\t\t}\r\n\t\t\treturn user;\r\n\t\t}\r\n\r\n /**\r\n * Clear Active User\r\n * @memberof UserFactory\r\n */\r\n\t\tfunction clearActiveUser() {\r\n\t\t\tlocalStorageMD5Service.remove('active');\r\n\t\t}\r\n\r\n /**\r\n * Save Active User \r\n * @memberof UserFactory\r\n * @param {Object} User\r\n */\r\n\t\tfunction setActiveUser(user) {\r\n\t\t\tif (user != null && user.aimsId != null) {\r\n\t\t\t\tvar value = {\r\n\t\t\t\t\taimsId: user.aimsId\r\n\t\t\t\t};\r\n\t\t\t\tlocalStorageMD5Service.set('active', value);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction azlogin(onsuccess, onerror, onfinally) {\r\n\t\t\treturn new Promise((resolve, reject) => {\r\n\t\t\t\tvar loginRequest = {\r\n\t\t\t\t\tscopes: [\"User.Read\"]\r\n\t\t\t\t};\r\n\t\t\t\tvar silentRequest = {\r\n\t\t\t\t\tscopes: [\"openid\", \"profile\", \"User.Read\"],\r\n\t\t\t\t\tredirectUri: \"http://localhost:3000/blank.html\"\r\n\t\t\t\t};\r\n\t\t\r\n\t\t\t\tif (username == null) {\r\n\t\t\t\t\tmyMSALObj.loginRedirect(loginRequest);\r\n\t\t\t\t\tresolve(); // Resolve immediately for redirect scenario\r\n\t\t\t\t} else {\r\n\t\t\t\t\tsilentRequest.account = myMSALObj.getAccountByUsername(username);\r\n\t\t\t\t\tvar token = null;\r\n\t\t\r\n\t\t\t\t\tmyMSALObj.acquireTokenSilent(silentRequest)\r\n\t\t\t\t\t\t.then(tokenResponse => {\r\n\t\t\t\t\t\t\tif (!tokenResponse.idToken) {\r\n\t\t\t\t\t\t\t\tLogService.error('response.idToken is undefined');\r\n\t\t\t\t\t\t\t\tnewLoginFailedAttemp(); // Run newLoginFailedAttemp() if idToken is undefined\r\n\t\t\t\t\t\t\t\treject(new Error('Token is not available')); // Reject the promise\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\ttoken = tokenResponse.idToken;\r\n\t\t\t\t\t\t\t\tlocalStorageMD5Service.remove('failedLoginAttemps');\r\n\t\t\t\t\t\t\t\tlogin(token, onsuccess, onerror, onfinally);\r\n\t\t\t\t\t\t\t\tresolve(); // Resolve after successful login\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t})\r\n\t\t\t\t\t\t.catch(error => {\r\n\t\t\t\t\t\t\tif (error instanceof msal.InteractionRequiredAuthError) {\r\n\t\t\t\t\t\t\t\tLogService.error(error, 'Fallback to interaction when silent call fails');\r\n\t\t\t\t\t\t\t\t // Handle the redirection process error here if needed\r\n\t\t\t\t\t\t\t\t myMSALObj.acquireTokenRedirect(silentRequest)\r\n\t\t\t\t\t\t\t\t .then(() => {\r\n\t\t\t\t\t\t\t\t\t // Continue with the process after successful redirection\r\n\t\t\t\t\t\t\t\t\t resolve();\r\n\t\t\t\t\t\t\t\t })\r\n\t\t\t\t\t\t\t\t .catch(redirectError => {\r\n\t\t\t\t\t\t\t\t\t LogService.error(redirectError, 'Error during redirection');\r\n\t\t\t\t\t\t\t\t\t newLoginFailedAttemp(); // Run newLoginFailedAttemp() for redirection errors\r\n\t\t\t\t\t\t\t\t\t reject(redirectError); // Reject the promise with the redirection error\r\n\t\t\t\t\t\t\t\t });\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tLogService.error(error, 'Failed to acquire token silently');\r\n\t\t\t\t\t\t\t\tnewLoginFailedAttemp(); // Run newLoginFailedAttemp() for other errors\r\n\t\t\t\t\t\t\t\treject(error); // Reject the promise with the error\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t})\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\r\n function azSignOut() {\r\n\r\n /**\r\n * You can pass a custom request object below. This will override the initial configuration. For more information, visit:\r\n * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/request-response-object.md#request\r\n */\r\n \r\n const logoutRequest = {\r\n account: myMSALObj.getAccountByUsername(username),\r\n postLogoutRedirectUri: window.location.href\r\n\r\n };\r\n \r\n myMSALObj.logoutRedirect(logoutRequest);\r\n }\r\n\r\n /**\r\n * Add code to try to login locally if remote login fails with a 404 or timeout\r\n * @memberof UserFactory\r\n * @param {string} token\r\n * @param {function} onsuccess callback function if the call is a success\r\n * @param {function} onerror callback function if the call failed\r\n * @param {function} onfinally callback function that runs on the end\r\n */\r\n\t\tfunction login(token,onsuccess, onerror, onfinally) {\r\n\t\t\tclearActiveUser();\r\n\t\t\tvar q = CabinAPIService.login(token);\r\n\t\t\tq.then(function (response) {\r\n\r\n\t\t\t\t// if the user that tries to log in is different than the last\r\n\t\t\t\t// logged in user, then reset all stored server data\r\n\t\t\t\tif (getUser() != null) {\r\n\t\t\t\t\tif (getUser().aimsId.toString() != response.data.data.aimsId.toString()) {\r\n\t\t\t\t\t\tDataCleanerFactory.deleteAllData();\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// delete any flights created locally, that do not have any local\r\n\t\t\t\t// reports\r\n\t\t\t\tDataCleanerFactory.deleteOrphanedLocalFlights();\r\n\r\n\t\t\t\t// assign the logged in user\r\n\t\t\t\tvar user = response.data.data;\r\n\r\n\t\t\t\tsetUser(user);\r\n\t\t\t\tsetActiveUser(user);\r\n\t\t\t\tif (typeof (onsuccess) == \"function\") {\r\n\t\t\t\t\tonsuccess();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tq.catch(function (response) {\r\n\t\t\t\tif (typeof (onerror) == \"function\") {\r\n\t\t\t\t\tonerror(response);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tq.finally(function (response) {\r\n\t\t\t\tif (typeof (onfinally) == \"function\") {\r\n\t\t\t\t\tonfinally();\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\treturn q;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* the function that extends the token for limited time if a user forgot their password\r\n\t\t* @memberof UserFactory\r\n\t\t* @param {function} onsuccess callback function if the call is a success\r\n\t\t* @param {function} onerror callback function if the call failed\r\n\t\t*/\r\n\t\tfunction extendToken(onsuccess, onerror) {\r\n\t\t\tvar user = getUser();\r\n\t\t\t$http.post(apiUrl + '/login/extendtoken', { 'Token': user.token }, { 'Content-Type': 'application/json' })\r\n\t\t\t\t.then(function (response) {\r\n\t\t\t\t\tuser.token = response.data.data;\r\n\t\t\t\t\tuser.tokenExtended = true;\r\n\t\t\t\t\tsetUser(user);\r\n\t\t\t\t\tsetActiveUser(user);\r\n\t\t\t\t\tif (typeof (onsuccess) == \"function\") {\r\n\t\t\t\t\t\tonsuccess();\r\n\t\t\t\t\t}\r\n\t\t\t\t}).catch(function (response) {\r\n\t\t\t\t\tif (typeof (onerror) == \"function\") {\r\n\t\t\t\t\t\tonerror(response);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\r\n\t\t}\r\n\r\n\t\tfunction getLoginFailedAttemps (){\r\n\t\t\tvar failedLoginAttemps = localStorageMD5Service.get('failedLoginAttemps');\r\n\t\t\tif(failedLoginAttemps){\r\n\t\t\t\treturn failedLoginAttemps;\r\n\t\t\t}\r\n\t\t\telse{\r\n\t\t\t\treturn 0;\r\n\t\t\t}\r\n\t\t}\r\n\t\tfunction newLoginFailedAttemp (){\r\n\t\t\tvar value = 1;\r\n\t\t\tvar failedLoginAttemps = localStorageMD5Service.get('failedLoginAttemps');\r\n\t\t\tif(failedLoginAttemps && failedLoginAttemps !== \"null\"){\r\n\t\t\t\tvar attempsToNumber = Number(failedLoginAttemps);\r\n\t\t\t\tvalue = value + attempsToNumber;\r\n\t\t\t}\r\n\t\t\tlocalStorageMD5Service.set('failedLoginAttemps', value);\r\n\t\t}\r\n\t\treturn service;\r\n\t}\r\n\r\n})();\r\n","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.factory('LuggageComplianceFactory', LuggageComplianceFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name LuggageComplianceFactory\r\n * @description \r\n * Add, Update, Delete and Get Luggage Compliance per passenger-flight\r\n * @ngInject\r\n */\r\n\tfunction LuggageComplianceFactory(GenericService, $http, apiUrl, $timeout) {\r\n\r\n\t\tvar objType = 'LuggageCompliance';\r\n\t\tvar objCallback = LuggageCompliance;\r\n\r\n /**\r\n * Initialize the Passenger Incident\r\n * @memberof LuggageComplianceFactory\r\n */\r\n\t\tfunction LuggageCompliance() {\r\n\t\t\tthis.GetId = GetId;\r\n\t\t\tthis.isSynced = false;\r\n\t\t}\r\n\r\n\t\tvar submitResponseObj = { success: false, message: '' }\r\n\t\tvar service = {\r\n\t\t\tsetAllLuggageComplianceToStorage : setAllLuggageComplianceToStorage,\r\n\t\t\tsetLuggageComplianceToStorage : setLuggageComplianceToStorage,\r\n\t\t\tsaveLuggageComplianceToStorage : saveLuggageComplianceToStorage,\r\n\t\t\tgetLuggageComplianceFromStorage : getLuggageComplianceFromStorage,\r\n\t\t\tupdateLuggageCompliance : updateLuggageCompliance,\r\n\t\t\tsaveLuggageCompliance : saveLuggageCompliance,\r\n\t\t\tgetLuggageComplianceByFlightId : getLuggageComplianceByFlightId,\r\n\t\t\tgetPassengerLuggageCompliance : getPassengerLuggageCompliance,\r\n\t\t\tremoveLuggageCompliance : removeLuggageCompliance,\r\n\t\t\tremovePendingsLuggageCompliance : removePendingsLuggageCompliance,\r\n\t\t\tremoveLuggageComplianceByFlightId : removeLuggageComplianceByFlightId,\r\n\t\t\tdeleteAllLuggageComplianceReportsByFlightId: deleteAllLuggageComplianceReportsByFlightId,\r\n\t\t\tsubmitLuggageCompliance : submitLuggageCompliance,\r\n\t\t\tsyncResultFormat : syncResultFormat,\r\n\t\t\tupdateLuggageComplianceStorage : updateLuggageComplianceStorage,\r\n\t\t\tsaveFlightIsCompliantToStorage: saveFlightIsCompliantToStorage,\r\n\t\t\tgetFlightCompliantStatus:getFlightCompliantStatus,\r\n\t\t\tcleanOldData: cleanOldData\r\n\t\t};\r\n\r\n\t\t\r\n\t\tfunction GetId(){\r\n\t\t\treturn this.LocalId;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Save All Luggage Compliance Passengers\r\n\t\t * @param {array} objList \r\n\t\t */\r\n\t\tfunction setAllLuggageComplianceToStorage(objList) {\r\n\t\t\tGenericService.saveAll(objList,objType);\r\n }\r\n\r\n\r\n\t\t/**\r\n\t\t * Add or Remove a Luggage Compliance Report\r\n\t\t * @param {object} luggageComplianceReport\r\n\t\t */\r\n\t\tfunction setLuggageComplianceToStorage(luggageComplianceReport){\r\n\t\t\tvar report = getPassengerLuggageCompliance(luggageComplianceReport.FlightId, luggageComplianceReport.UCI);\r\n\r\n\t\t\tif(report && !luggageComplianceReport.isChecked){\r\n\t\t\t\tremoveLuggageCompliance(report.LocalId);\r\n\t\t\t}\r\n\t\t\telse if(luggageComplianceReport.isChecked){\r\n\t\t\t\tsaveLuggageCompliance(luggageComplianceReport);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Add a Luggage Compliance Report if it doesn't already exist, when this function is executed in loop it needs the index of report to prevent same LocalIds.\r\n\t\t * @param {object} luggageComplianceReport\r\n\t\t * @param {object} reportIndex\r\n\t\t */\r\n\t\tfunction saveLuggageComplianceToStorage(luggageComplianceReport, reportIndex){\r\n\t\t\tif(!reportIndex){\r\n\t\t\t\treportIndex = 0;\r\n\t\t\t}\r\n\t\t\tvar report = getPassengerLuggageCompliance(luggageComplianceReport.FlightId, luggageComplianceReport.UCI);\r\n\t\t\tif(!report){\r\n\t\t\t\t//use reportIndex to prevent same LocalId value\r\n\t\t\t\tsaveLuggageCompliance(luggageComplianceReport, reportIndex);\r\n\t\t\t}\r\n\t\t}\r\n\t\t/**\r\n\t\t * Add a Luggage Compliance Report for whole flight if it doesn't already exist\r\n\t\t * @param {object} luggageComplianceReport\r\n\t\t */\r\n\t\tfunction saveFlightIsCompliantToStorage(luggageComplianceReport){\r\n\t\t\tvar luggageComplianceReports = getLuggageComplianceByFlightId(luggageComplianceReport.FlightId);\r\n\t\t\tvar report = luggageComplianceReports.find(x => x.IsFlightCompliant===true);\r\n\t\t\tif(!report){\r\n\t\t\t\tsaveLuggageCompliance(luggageComplianceReport);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Get all luggage compliance reports of a flight\r\n\t\t * @param {number} flightId \r\n\t\t */\r\n\t\tfunction getLuggageComplianceByFlightId(flightId) {\r\n\t\t\tvar allReports = getLuggageComplianceFromStorage();\r\n\t\t\tvar flightReports = allReports.filter(x => x.FlightId==flightId);\r\n\t\t\treturn flightReports;\r\n\t\t};\r\n\r\n\t\tfunction getFlightCompliantStatus(flightId) {\r\n\t\t\tvar returnStatus = {IsFlightCompliant: false, Status: '', HasPendingsReports: false};\r\n\t\t\tvar luggageComplianceReports = getLuggageComplianceByFlightId(flightId);\r\n\t\t\tvar flightCompliantReport = luggageComplianceReports.find(x=>x.IsFlightCompliant);\r\n\t\t\tif(flightCompliantReport){\r\n\t\t\t\treturnStatus.IsFlightCompliant = true;\r\n\t\t\t\tif(flightCompliantReport.isSynced){\r\n\t\t\t\t\treturnStatus.Status = 'synced';\r\n\t\t\t\t}else{\r\n\t\t\t\t\treturnStatus.Status = 'pending';\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturnStatus.HasPendingsReports = luggageComplianceReports.some(s=>!s.IsFlightCompliant && !s.isSynced);\r\n\r\n\t\t\treturn returnStatus;\r\n\t\t} \r\n\t\r\n\r\n\t\t/**\r\n\t\t * Get all luggage compliance reports\r\n\t\t */\r\n\t\tfunction getLuggageComplianceFromStorage(){\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Get luggage compliance report for a specific passenger in a specific flight\r\n\t\t * @param {number} flightId \r\n\t\t * @param {number} uci \r\n\t\t */\r\n\t\tfunction getPassengerLuggageCompliance(flightId, uci){\r\n\t\t\tvar luggageComplianceReports = getLuggageComplianceByFlightId(flightId);\r\n\t\t\tvar passengerReport = luggageComplianceReports.find(x => x.UCI==uci);\r\n\t\t\treturn passengerReport;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Update a luggage compliance report (Search by FlightId-UCI)\r\n\t\t * @param {object} luggageComplianceReport \r\n\t\t */\r\n\t\tfunction updateLuggageCompliance(luggageComplianceReport){\r\n\t\t\tGenericService.save(luggageComplianceReport, objType, objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Create a new luggage compliance report\r\n\t\t * @param {object} luggageComplianceReport \r\n\t\t */\r\n\t\tfunction saveLuggageCompliance(luggageComplianceReport, reportIndex){\r\n\t\t\tif(!reportIndex){\r\n\t\t\t\treportIndex = 0;\r\n\t\t\t}\r\n\t\t\tluggageComplianceReport.LocalId = moment().valueOf() + reportIndex;\r\n\t\t\tluggageComplianceReport.isSynced = false;\r\n GenericService.add(luggageComplianceReport, objType, objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Remove customer event from storage\r\n\t\t * @param {number} luggageComplianceReportId \r\n\t\t */\r\n\t\tfunction removeLuggageCompliance(luggageComplianceReportId){\r\n\t\t\tGenericService.remove(luggageComplianceReportId, objType, objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Remove all pendings luggage compliance reports in a flight from storage\r\n\t\t * @param {number} flightId \r\n\t\t */\r\n\t\tfunction removePendingsLuggageCompliance(flightId){\r\n\t\t\tvar pendingReports = getLuggageComplianceByFlightId(flightId).filter(x => !x.isSynced);\r\n\t\t\tif(pendingReports){\r\n\t\t\t\tpendingReports.forEach(function(unsyncedReport){\r\n\t\t\t\t\tremoveLuggageCompliance(unsyncedReport.LocalId);\t\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Remove all luggage compliance reports in a flight from storage\r\n\t\t * @param {number} flightId \r\n\t\t */\r\n\t\t function removeLuggageComplianceByFlightId(flightId){\r\n\t\t\tvar reports = getLuggageComplianceByFlightId(flightId);\r\n\t\t\tif(reports){\r\n\t\t\t\treports.forEach(function(report){\r\n\t\t\t\t\tremoveLuggageCompliance(report.LocalId);\t\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Delete all luggage compliance reports of this flight from db and then from local storage\r\n\t\t * @param {number} flightId \r\n\t\t */\r\n\t\tfunction deleteAllLuggageComplianceReportsByFlightId(flightId){\r\n\t\t\treturn $http.post(apiUrl + '/LuggageCompliance/ResetLuggageCompliance', flightId, { 'Content-Type': 'application/json' })\r\n\t\t\t.then(res => deleteReportsSuccessCallBack(res, flightId))\r\n\t\t\t.catch(res => saveReportFailedCallBack(res));\r\n\t\t}\r\n\r\n\t\t/**\r\n * The callback function upon successful submit\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} submitResponseObj\r\n */\r\n\t\tfunction deleteReportsSuccessCallBack(res, flightId) {\r\n\t\t\tsubmitResponseObj.success = res.data.success;\r\n\r\n if (res.data.success) {\r\n\t\t\t\tremoveAllLuggageCompliance(flightId);\r\n\t\t\t\tsubmitResponseObj.message = \"Success\";\r\n }\r\n else {\r\n submitResponseObj.message = res.data.errorMessage\r\n }\r\n return submitResponseObj;\r\n\t\t}\r\n\t\t\r\n\t\t/**\r\n\t\t * Remove all luggage compliance reports of this flight from storage\r\n\t\t * @param {number} flightId \r\n\t\t */\r\n\t\tfunction removeAllLuggageCompliance(flightId){\r\n\t\t\tvar allReports = getLuggageComplianceByFlightId(flightId);\r\n\t\t\tif(allReports){\r\n\t\t\t\tallReports.forEach(function(report){\r\n\t\t\t\t\tremoveLuggageCompliance(report.LocalId);\t\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n * Sends flight's pending luggage compliance reports\r\n * @param {number} flightId The Flight identifier\r\n * @returns {promise} submitResponseObj\r\n */\r\n function submitLuggageCompliance(flightId) {\r\n var pendingReports = getLuggageComplianceByFlightId(flightId).filter(x => !x.isSynced);\r\n\r\n\t\t\tvar postData = {\r\n\t\t\t\t\"FlightId\": flightId,\r\n\t\t\t\t\"LuggageCompliance\" : pendingReports\r\n\t\t\t};\r\n\r\n return $http.post(apiUrl + '/LuggageCompliance/Post', postData, { 'Content-Type': 'application/json' })\r\n .then(res => saveReportSuccessCallBack(res, pendingReports, flightId))\r\n .catch(res => saveReportFailedCallBack(res));\r\n\t\t}\r\n\t\t\r\n\t\t /**\r\n * The callback function upon successful submit\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} submitResponseObj\r\n */\r\n\t\t function saveReportSuccessCallBack(res, pendingReports, flightId) {\r\n\t\t\tsubmitResponseObj.success = res.data.success;\r\n if (res.data.success) {\r\n\t\t\t\tupdateLuggageComplianceStorage(res.data.data.LuggageComplianceReports, flightId);\r\n\t\t\t\tsubmitResponseObj.message = \"Success! Your input has been sent\";\r\n\t\t\t\t\r\n }\r\n else {\r\n submitResponseObj.message = res.data.errorMessage\r\n }\r\n return submitResponseObj;\r\n }\r\n\r\n /**\r\n * The callback function upon failure on submit\r\n * @returns {object} submitResponseObj\r\n */\r\n function saveReportFailedCallBack(res) {\r\n submitResponseObj.success = false;\r\n submitResponseObj.message = \"Oops! Something went wrong\"\r\n return submitResponseObj;\r\n }\r\n\r\n\t\t/**\r\n\t\t * Shows sync result in dlgSync\r\n\t\t * @param {object} result Sync result status\r\n\t\t */\r\n\t\tfunction syncResultFormat(result) {\r\n\t\t\tvar updateText;\r\n\t\t\tvar upClass;\r\n\r\n\t\t\tif (result.ResponseSuccess == null) {\r\n\t\t\t\tupdateText = \"No One Piece Compliance Checks were uploaded to the server. \";\r\n\t\t\t\tupClass = \"alert-cyan\";\r\n\t\t\t} else if (result.ResponseSuccess == true) {\r\n\t\t\t\tupdateText = \"One Piece Compliance Checks were uploaded to the server. \";\r\n\t\t\t\tupClass = \"alert-cyan\";\r\n\r\n\t\t\t\tupdateAllPendingsToSynced(result.LuggageComplianceReports);\r\n\t\t\t} else {\r\n\t\t\t\tupdateText = \"One Piece Compliance Checks failed to be uploaded to the server. \";\r\n\t\t\t\tupClass = \"alert-deep-orange\";\r\n\r\n\t\t\t\tcleanOldPendingChecks();\r\n\t\t\t}\r\n\r\n\t\t\treturn {\r\n\t\t\t\tupdMessage: updateText,\r\n\t\t\t\tupdClass: upClass\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * When sync succeed, update the pending luggage reports to synced\r\n\t\t */\r\n\t\tfunction updateAllPendingsToSynced(syncedReports){\r\n\t\t\tvar syncedReportsFromLS = getLuggageComplianceFromStorage().filter(x => x.isSynced);\r\n\r\n\t\t\tsyncedReports.forEach(function(syncedReport, index){\r\n\t\t\t\tsyncedReport.isSynced = true;\r\n\t\t\t\tsyncedReport.LocalId = moment().valueOf() + index;\r\n\r\n\t\t\t\tsyncedReportsFromLS.push(syncedReport);\r\n\t\t\t});\r\n\t\t\tsetAllLuggageComplianceToStorage(syncedReportsFromLS);\r\n\t\t}\r\n\r\n\r\n\t\t/**\r\n\t\t * When sync fails, check for 2 day old checks and delete them\r\n\t\t */\r\n\t\tfunction cleanOldPendingChecks(){\r\n\t\t\tvar unsyncedReports = getLuggageComplianceFromStorage().filter(x => !x.isSynced);\r\n\r\n\r\n\t\t\tvar today = new Date();\r\n\t\t\tvar trimmedToday = new Date(today);\r\n\t\t\tunsyncedReports.forEach(function(unsyncedReport){\r\n\t\t\t\tvar createdDay = new Date(unsyncedReport.Created);\r\n\t\t\t\tvar trimmedDay = new Date(createdDay);\r\n\t\t\t\tvar diffDays = Date.DifferenceInDays(trimmedToday.trimTime(), trimmedDay.trimTime());\r\n\t\t\t\tif(diffDays >= 2){\r\n\t\t\t\t\tremoveLuggageCompliance(unsyncedReport.LocalId);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\t\t\r\n \r\n\r\n\t\tfunction updateLuggageComplianceStorage(LuggageComplianceReports, flightId){\r\n\t\t\t\r\n\t\t\tvar allLuggageReports = getLuggageComplianceFromStorage();\r\n\t\t\tvar luggageReports = allLuggageReports.filter(x => x.FlightId!=flightId);\r\n\t\t\tLuggageComplianceReports.forEach(function(syncedReport, index){\r\n\t\t\t\tsyncedReport.isSynced = true;\r\n\t\t\t\tsyncedReport.LocalId = moment().valueOf() + index;\r\n\r\n\t\t\t\tluggageReports.push(syncedReport);\r\n\t\t\t});\r\n\t\t\tsetAllLuggageComplianceToStorage(luggageReports);\r\n\t\t\t\r\n\t\t}\r\n\r\n \t/**\r\n * Clean ls from old luggage reports\r\n * @param {array} flights Synced flights\r\n */\r\n\t\tfunction cleanOldData(responseFlightIds){\r\n\t\t\tvar allLuggageReports = getLuggageComplianceFromStorage();\r\n\t\t\t\r\n\t\t\t//Filter out Philoxenia Questions of old flights\r\n\t\t\tallLuggageReports = allLuggageReports.filter(x => x != null && responseFlightIds.includes(x.FlightId));\r\n\t\t\t\r\n\t\t\tsetAllLuggageComplianceToStorage(allLuggageReports);\r\n\t\t}\r\n\r\n\r\n\t\treturn service;\r\n\t}\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('twoLuggageEvents', twoLuggageEvents);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name twoLuggageEvents\r\n * @restrict E\r\n * @description\r\n * Implementation of twoLuggageEvents\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function twoLuggageEvents(LuggageComplianceFactory, PaxInfoFactory, $timeout) {\r\n function link(scope) {\r\n scope.submit = submit;\r\n scope.reset = resetConfirm;\r\n scope.resetSynced = resetSyncedConfirm;\r\n scope.allPassengersAreComplianceConfirmation = allPassengersAreComplianceConfirmation; \r\n \r\n\r\n getLuggageCompliancePassengers();\r\n\r\n function getLuggageCompliancePassengers(){\r\n scope.hasSyncedPassengers = false;\r\n scope.Passengers = [];\r\n scope.pendingReports = [];\r\n var flightId = scope.flight.FlightId;\r\n\r\n scope.flightCompliant = LuggageComplianceFactory.getFlightCompliantStatus(flightId);\r\n \r\n //Get cabin luggage compliance reports for this flight\r\n var luggageComplianceReports = LuggageComplianceFactory.getLuggageComplianceByFlightId(flightId);\r\n\r\n //Get pax info\r\n PaxInfoFactory.getPaxInfoFromStorage(flightId, function (paxinfo) {\r\n if(paxinfo){\r\n luggageComplianceReports.forEach(function (luggageReport) {\r\n var columns = [];\r\n paxinfo.Seatmap.forEach(function(row){\r\n row.Columns.forEach(function(column){\r\n columns.push(column);\r\n });\r\n });\r\n \r\n var pax = columns.find(p => p.UCI == luggageReport.UCI);\r\n if(pax){\r\n \r\n //Passenger already exists - Only add events\r\n if(scope.Passengers.map(p => p.UCI).includes(luggageReport.UCI)){\r\n scope.Passengers.find(p => p.UCI == luggageReport.UCI).isSynced = luggageReport.isSynced;\r\n }\r\n //Add Passenger Info & Events\r\n else{\r\n var passenger = {\r\n UCI: luggageReport.UCI,\r\n isSynced : luggageReport.isSynced,\r\n Name : pax.Fullname,\r\n SeatNo : pax.SeatNo,\r\n HasTwoLuggage: true,\r\n isOpen: false\r\n };\r\n scope.Passengers.push(passenger);\r\n }\r\n if(scope.Passengers.some(x => x.isSynced)){\r\n scope.hasSyncedPassengers = true;\r\n }\r\n }\r\n });\r\n }\r\n\r\n scope.pendingReports = scope.Passengers.filter(p => !p.isSynced);\r\n\r\n //Get flightIsCompliant report\r\n var flightIsCompliantReport = luggageComplianceReports.find(p => !p.isSynced && p.IsFlightCompliant);\r\n if(flightIsCompliantReport){\r\n scope.pendingReports.push(flightIsCompliantReport);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Opens confirmation modal when undo is requested on an approved proposal\r\n * @memberof proposal\r\n */\r\n function allPassengersAreComplianceConfirmation() {\r\n if(!scope.flightCompliant.HasPendingsReports){\r\n applyAllPassengersAreCompliant();\r\n }\r\n else if (!scope.flightCompliant.IsFlightCompliant && scope.flightCompliant.HasPendingsReports){\r\n bootbox.dialog({\r\n message: ' All pending reports of passengers with 2 items on board will be cleared.',\r\n title: \"Confirm\",\r\n buttons: {\r\n confirm:{\r\n label: 'Confirm',\r\n className: \"btn-success\",\r\n callback: function(){\r\n applyAllPassengersAreCompliant();\r\n }\r\n }, \r\n cancel:{\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function(){}\r\n }\r\n }\r\n });\r\n }\r\n \r\n }\r\n\r\n /**\r\n * Reset all synced luggage compliance reports of this flight and refresh\r\n */\r\n function resetSyncedConfirm(){\r\n bootbox.dialog({\r\n message: ' Reset synced reports.',\r\n title: \"Confirm\",\r\n buttons: {\r\n confirm:{\r\n label: 'Confirm',\r\n className: \"btn-warning\",\r\n callback: function(){\r\n resetAll();\r\n getLuggageCompliancePassengers();\r\n }\r\n }, \r\n cancel:{\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function(){}\r\n }\r\n }\r\n });\r\n }\r\n \r\n /**\r\n * Reset all pendings luggage compliance reports of this flight and refresh\r\n */\r\n function resetConfirm(){\r\n bootbox.dialog({\r\n message: ' Reset all pending reports of passengers with 2 items on board.',\r\n title: \"Confirm\",\r\n buttons: {\r\n confirm:{\r\n label: 'Confirm',\r\n className: \"btn-warning\",\r\n callback: function(){\r\n resetAllPendings();\r\n getLuggageCompliancePassengers();\r\n }\r\n }, \r\n cancel:{\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function(){}\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Create or remove pending AllPassengersAreCompliant report of this flight\r\n */\r\n function applyAllPassengersAreCompliant(){\r\n if(scope.flightCompliant.HasPendingsReports || scope.flightCompliant.Status === 'pending'){\r\n resetAllPendings();\r\n }\r\n if(!scope.flightCompliant.IsFlightCompliant){\r\n applyFlightComplianceReport();\r\n }\r\n getLuggageCompliancePassengers();\r\n }\r\n\r\n function applyFlightComplianceReport(){\r\n var cabinLuggageReport = {\r\n PNR : '',\r\n UCI : '',\r\n FlightId : scope.flight.FlightId,\r\n FareFamily: '',\r\n IsFlightCompliant: true,\r\n Created: moment()\r\n };\r\n LuggageComplianceFactory.saveFlightIsCompliantToStorage(cabinLuggageReport);\r\n }\r\n \r\n function resetAllPendings(){\r\n LuggageComplianceFactory.removePendingsLuggageCompliance(scope.flight.FlightId);\r\n }\r\n /**\r\n * Deletes all luggage compliance reports of this flight from DB and from local storage\r\n */\r\n function resetAll(){\r\n if(scope.isOffline){\r\n scope.showPanel = \"offline\";\r\n }\r\n else{\r\n scope.showPanel = \"loading\";\r\n LuggageComplianceFactory.deleteAllLuggageComplianceReportsByFlightId(scope.flight.FlightId)\r\n .then(res => handleSubmitResponse(res));\r\n }\r\n }\r\n \r\n /**\r\n * Submit pending luggage compliance reports of this flight\r\n */\r\n function submit(){\r\n var flightId = scope.flight.FlightId;\r\n if(scope.isOffline){\r\n scope.showPanel = \"offline\";\r\n }\r\n else{\r\n scope.showPanel = \"loading\";\r\n LuggageComplianceFactory.submitLuggageCompliance(flightId)\r\n .then(res => handleSubmitResponse(res));\r\n }\r\n }\r\n\r\n /**\r\n * Manage API response\r\n * @param {object} res \r\n */\r\n function handleSubmitResponse(res) {\r\n getLuggageCompliancePassengers();\r\n if (res.success) {\r\n manageResponseMessage(\"success\", res.message);\r\n $timeout(function () { scope.showPanel = \"luggageCompliance\"; }, 6000);\r\n }\r\n else {\r\n manageResponseMessage(\"failure\", res.message);\r\n }\r\n }\r\n\r\n /**\r\n * Manage message alerts\r\n * @param {string} panelToShow \r\n * @param {string} message \r\n */\r\n function manageResponseMessage(panelToShow, message) {\r\n scope.submitMessage = message;\r\n scope.showPanel = panelToShow;\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/LuggageCompliance/twoLuggageEvents.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('CalendarRedirectModalCtrl', CalendarRedirectModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CalendarRedirectModalCtrl\r\n * @description \r\n * Modal to redirect to Calendar after all mandatory memos are read\r\n * @ngInject\r\n */\r\nfunction CalendarRedirectModalCtrl($scope, $location, $uibModalInstance) {\r\n $scope.gotoCalendar = gotoCalendar;\r\n\r\n \r\n function gotoCalendar(){\r\n cancel();\r\n $location.path('/');\r\n }\r\n \r\n /**\r\n * Closes modal\r\n * @memberof CalendarRedirectModalCtrl\r\n */\r\n function cancel() {\r\n $uibModalInstance.close('cancel');\r\n }\r\n }\r\n\r\n \r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('MandatoryModalCtrl', MandatoryModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name MandatoryModalCtrl\r\n * @description \r\n * Warning Modal about unread mandatory memos\r\n * @ngInject\r\n */\r\nfunction MandatoryModalCtrl($scope, mandatoryUnread, MemoFactory, $uibModal, $routeParams, $location, $uibModalInstance) {\r\n $scope.mandatoryUnread = mandatoryUnread;\r\n $scope.gotoMandatoryUnreadMemos = gotoMandatoryUnreadMemos;\r\n\r\n function gotoMandatoryUnreadMemos(){\r\n $location.path('/memos/unreadMandatory');\r\n cancel();\r\n }\r\n \r\n /**\r\n * Closes modal\r\n * @memberof ProposalInfoModalCtr\r\n */\r\n function cancel() {\r\n $uibModalInstance.close('cancel');\r\n }\r\n }\r\n\r\n \r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('MemoFactory', MemoFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name MemoFactory\r\n * @description \r\n * Add, Update, Delete and Get Memos.\r\n * @ngInject\r\n */\r\n function MemoFactory(FlightFactory, GroundDutyFactory, IndexedDBService, PaxInfoFactory, $q) {\r\n\r\n /**\r\n * Initialize the Memo\r\n * @memberof MemoFactory\r\n */\r\n function Memo() {\r\n this.Id = null;\r\n this.expired = false;\r\n }\r\n\r\n var objType = 'Memos';\r\n var objCallback = Memo;\r\n\r\n var service = {\r\n getMemosFromStorage: getMemosFromStorage,\r\n setMemosToStorage: setMemosToStorage,\r\n clearMemosFromStorage: clearMemosFromStorage,\r\n getMemosForFlight: getMemosForFlight,\r\n getStoredMemosIds: getStoredMemosIds,\r\n saveOneMemoToStorage: saveOneMemoToStorage,\r\n addMemoToStorage: addMemoToStorage,\r\n deleteMemoFromStorage: deleteMemoFromStorage,\r\n setMemosFromServer: setMemosFromServer,\r\n getMemosForGroundDuty: getMemosForGroundDuty,\r\n getMemosForCrewRoute: getMemosForCrewRoute,\r\n getUnreadMemos: getUnreadMemos,\r\n getMandatoryUnreadMemos: getMandatoryUnreadMemos,\r\n getAllUnreadGroundDutyMemos: getAllUnreadGroundDutyMemos,\r\n markGroundDutiesUnread: markGroundDutiesUnread,\r\n info: info,\r\n getNotHiddenMemos: getNotHiddenMemos\r\n };\r\n\r\n /**\r\n * Get Memos\r\n * @memberof MemoFactory\r\n * @param {function} callback \r\n */\r\n function getMemosFromStorage(callback) {\r\n //return GenericService.list(objType,objCallback);\r\n IndexedDBService.getAll(objType).then(function (results) {\r\n callback(results);\r\n });\r\n };\r\n\r\n /**\r\n * Set Memos\r\n * @memberof MemoFactory\r\n * @param {array} Memos a list of memos to set to indexedDB\r\n */\r\n function setMemosToStorage(Memos) {\r\n IndexedDBService.addAll(objType, Memos);\r\n };\r\n\r\n /**\r\n * Update Memo to Storage\r\n * @memberof MemoFactory\r\n * @param {object} Memo a memo\r\n */\r\n function saveOneMemoToStorage(Memo) {\r\n IndexedDBService.put(objType, Memo);\r\n };\r\n\r\n function info() {\r\n IndexedDBService.info(objType);\r\n }\r\n\r\n /**\r\n * Add Memo to Storage\r\n * @memberof MemoFactory\r\n * @param {object} Memo a memo\r\n */\r\n function addMemoToStorage(Memo) {\r\n IndexedDBService.add(objType, Memo);\r\n };\r\n\r\n /**\r\n * Delete Memo from Storage\r\n * @memberof MemoFactory\r\n * @param {number} MemoId The unique Identifier of the Memo\r\n */\r\n function deleteMemoFromStorage(MemoId) {\r\n IndexedDBService.remove(objType, MemoId);\r\n };\r\n\r\n /**\r\n * Clear Memo from Storage\r\n * @memberof MemoFactory\r\n */\r\n function clearMemosFromStorage() {\r\n IndexedDBService.removeAll(objType);\r\n };\r\n\r\n function ValidateCountryCategory(criteria, isDepartureCategory, isArrivalCategory) {\r\n var isValid = false;\r\n if (criteria.Special == \"Specific\") {\r\n isValid = ((criteria.Field == \"Intra\" && isDepartureCategory) || (criteria.Field == \"Extra\" && !isDepartureCategory))\r\n && ((criteria.FieldOptional == \"Intra\" && isArrivalCategory) || (criteria.FieldOptional == \"Extra\" && !isArrivalCategory));\r\n }\r\n else {\r\n if (criteria.Field == \"Intra\") {\r\n isValid = (isDepartureCategory && criteria.Special != \"To\") || (isArrivalCategory && criteria.Special != \"From\");\r\n }\r\n else if (criteria.Field == \"Extra\") {\r\n isValid = (!isDepartureCategory && criteria.Special != \"To\") || (!isArrivalCategory && criteria.Special != \"From\");\r\n }\r\n }\r\n return isValid;\r\n }\r\n\r\n function isValid(field, departureField, arrivalField, special) {\r\n var isValid = false;\r\n\r\n var isDeparture = departureField == field;\r\n var isArrival = arrivalField == field;\r\n\r\n if (special == \"From\") {\r\n isValid = isDeparture\r\n } else if (special == \"To\") {\r\n isValid = isArrival;\r\n } else {\r\n isValid = isArrival || isDeparture;\r\n }\r\n\r\n return isValid;\r\n }\r\n\r\n /**\r\n * Gets all unread memos related to a Ground Duty\r\n * @memberof MemoFactory\r\n */\r\n function getAllUnreadGroundDutyMemos(callback) {\r\n getMemosFromStorage(function (results) {\r\n var memosCollection = results;\r\n var unreadGroundDutyMemos = [];\r\n for (var i = 0; i < memosCollection.length; i++) {\r\n for (var j = 0; j < memosCollection[i].MemoCriteria.length; j++) {\r\n var item = memosCollection[i].MemoCriteria[j];\r\n if (item.QueryType == \"GroundDutyCode\" && memosCollection[i].ReadDt == null) {\r\n unreadGroundDutyMemos.push(memosCollection[i]);\r\n break;\r\n }\r\n }\r\n\r\n }\r\n callback(unreadGroundDutyMemos);\r\n });\r\n }\r\n\r\n function getMemosForGroundDuty(Id, callback) {\r\n var groundDuty = GroundDutyFactory.getGroundDutyFromStorage(Id);\r\n\r\n if (!groundDuty) {\r\n return [];\r\n }\r\n\r\n getMemosFromStorage(function (results) {\r\n var memosCollection = results;\r\n var groundDutyMemos = [];\r\n\r\n var fromDutyDate = new Date(groundDuty.DutyDate).getTime();\r\n var toDutyDate = new Date(groundDuty.DutyDate).getTime();\r\n\r\n for (var i = 0; i < memosCollection.length; i++) {\r\n\r\n if (new Date(memosCollection[i].ValidFrom).getTime() <= fromDutyDate && new Date(memosCollection[i].ValidTo).getTime() >= toDutyDate) {\r\n for (var j = 0; j < memosCollection[i].MemoCriteria.length; j++) {\r\n var item = memosCollection[i].MemoCriteria[j];\r\n if (item.QueryType == \"GroundDutyCode\" && (item.Field == groundDuty.DutyNo || item.Field == groundDuty.GroundDutyNo)) {\r\n groundDutyMemos.push(memosCollection[i]);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n callback(groundDutyMemos);\r\n });\r\n }\r\n /**\r\n * Get Memos that are relate to this flight\r\n * @memberof MemoFactory\r\n * @param {number} Id The unique Identifier of the Memo\r\n * @param {function} callback The callback function\r\n */\r\n function getMemosForFlight(Id, callback) {\r\n var flight = FlightFactory.getFlightFromStorage(Id);\r\n if (!flight) {\r\n flight = FlightFactory.getLocalFlightFromStorage(Id);\r\n }\r\n\r\n if (!flight) {\r\n return [];\r\n }\r\n\r\n getMemosFromStorage(function (results) {\r\n var memosCollection = results;\r\n var flightMemos = [];\r\n PaxInfoFactory.getPaxInfoFromStorage(flight.FlightId, function (paxInfo) {\r\n for (var i = 0; i < memosCollection.length; i++) {\r\n\r\n if (new Date(memosCollection[i].ValidFrom).getTime() <= new Date(flight.ScheduledDeparture).getTime() && new Date(memosCollection[i].ValidTo).getTime() >= new Date(flight.ScheduledArrival).getTime()) {\r\n for (var j = 0; j < memosCollection[i].MemoCriteria.length; j++) {\r\n var item = memosCollection[i].MemoCriteria[j];\r\n if (\r\n (item.AcRegistration == flight.AcTailNo) ||\r\n (item.QueryType == \"Airport\" && isValid(item.Airport, flight.Departure, flight.Arrival, item.Special)) ||\r\n (item.FlightNo == flight.FlightNo) ||\r\n (item.AcType == flight.AcType) ||\r\n (isValidZone(item, flight.Zones)) ||\r\n (item.RouteStart == flight.Departure && item.RouteEnd == flight.Arrival) ||\r\n (item.ViceVersa && (item.RouteStart == flight.Arrival && item.RouteEnd == flight.Departure)) ||\r\n (item.QueryType == \"Country\" && isValid(item.Country, flight.DepartureCountry, flight.ArrivalCountry, item.Special)) ||\r\n (item.QueryType == \"Schengen\" && ValidateCountryCategory(item, flight.DepartureSchengen, flight.ArrivalSchengen)) ||\r\n (item.QueryType == \"European\" && ValidateCountryCategory(item, flight.DepartureEU, flight.ArrivalEU)) ||\r\n (paxInfo && (item.QueryType == \"SsrCode\" && PassengersHasSsrCode(paxInfo, item))) ||\r\n (item.QueryType == \"TrainingId\" && item.Field == flight.TrainingIndicatorId)\r\n ) {\r\n flightMemos.push(memosCollection[i]);\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n callback(flightMemos);\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Get Memos that are related to this crew route, by combining multiple flight and groundDuty memos \r\n * @memberof MemoFactory\r\n * @param {number} DutyNo Crew Route Identifier\r\n * @param {number} DutyDay Crew Route Day\r\n * @param {function} callback The callback function\r\n */\r\n function getMemosForCrewRoute(DutyNo, DutyDay, callback) {\r\n var groundDuties = GroundDutyFactory.getGroundDutiesByDutyNo(DutyNo, DutyDay);\r\n var flights = FlightFactory.getFlightsByDutyNo(DutyNo, DutyDay);\r\n\r\n PaxInfoFactory.getAllPaxInfoFromStorage(function (paxInfoResult) {\r\n getMemosFromStorage(function (results) {\r\n var memosCollection = results;\r\n var allMemos = [];\r\n\r\n for (var i = 0; i < memosCollection.length; i++) {\r\n var inserted = false;\r\n //first check if memo is connected with any groundDuties\r\n for (var g = 0; g < groundDuties.length; g++) {\r\n var fromDutyDate = new Date(groundDuties[g].DutyDate).getTime();\r\n var toDutyDate = new Date(groundDuties[g].DutyDate).getTime();\r\n if (new Date(memosCollection[i].ValidFrom).getTime() <= fromDutyDate && new Date(memosCollection[i].ValidTo).getTime() >= toDutyDate) {\r\n for (var j = 0; j < memosCollection[i].MemoCriteria.length; j++) {\r\n var item = memosCollection[i].MemoCriteria[j];\r\n if (item.QueryType == \"GroundDutyCode\" && (item.Field == groundDuties[g].DutyNo || item.Field == groundDuties[g].GroundDutyNo)) {\r\n allMemos.push(memosCollection[i]);\r\n inserted = true;\r\n break;\r\n }\r\n }\r\n }\r\n if (inserted) break; //don't check other groundDuties - memo is already inserted\r\n }\r\n //if memo was checked for all groundDuties and was not connected with any, check in flights\r\n if (!inserted) {\r\n for (var f = 0; f < flights.length; f++) {\r\n var paxInfo = null;\r\n if (new Date(memosCollection[i].ValidFrom).getTime() < new Date(flights[f].ScheduledDeparture).getTime() && new Date(memosCollection[i].ValidTo).getTime() > new Date(flights[f].ScheduledArrival).getTime()) {\r\n //check if flight has paxInfo \r\n for (var p = 0; p < paxInfoResult.length; p++) {\r\n if (paxInfoResult[p].FlightId == flights[f].FlightId) {\r\n paxInfo = paxInfoResult[p];\r\n break;\r\n }\r\n }\r\n for (var j = 0; j < memosCollection[i].MemoCriteria.length; j++) {\r\n var item = memosCollection[i].MemoCriteria[j];\r\n if (\r\n (item.AcRegistration == flights[f].AcTailNo) ||\r\n (item.QueryType == \"Airport\" && isValid(item.Airport, flights[f].Departure, flights[f].Arrival, item.Special)) ||\r\n (item.FlightNo == flights[f].FlightNo) ||\r\n (item.AcType == flights[f].AcType) ||\r\n (isValidZone(item.Zone, flights[f].Zones)) ||\r\n (item.RouteStart == flights[f].Departure && item.RouteEnd == flights[f].Arrival) ||\r\n (item.ViceVersa && (item.RouteStart == flights[f].Arrival && item.RouteEnd == flights[f].Departure)) ||\r\n (item.QueryType == \"Country\" && isValid(item.Country, flights[f].DepartureCountry, flights[f].ArrivalCountry, item.Special)) ||\r\n (item.QueryType == \"Schengen\" && ValidateCountryCategory(item, flights[f].DepartureSchengen, flights[f].ArrivalSchengen)) ||\r\n (item.QueryType == \"European\" && ValidateCountryCategory(item, flights[f].DepartureEU, flights[f].ArrivalEU)) ||\r\n (paxInfo && (item.QueryType == \"SsrCode\" && PassengersHasSsrCode(paxInfo, item))) ||\r\n (item.QueryType == \"TrainingId\" && item.Field == flights[f].TrainingIndicatorId)\r\n ) {\r\n allMemos.push(memosCollection[i]);\r\n inserted = true;\r\n break;\r\n }\r\n }\r\n }\r\n if (inserted) break; //don't check other flights - memo is already inserted\r\n }\r\n }\r\n }\r\n callback(allMemos);\r\n });\r\n });\r\n\r\n }\r\n\r\n function PassengersHasSsrCode(paxInfo, memoCriterion) {\r\n var retVal = false;\r\n for (var key in paxInfo.PassengerSummaryY) {\r\n if (key === memoCriterion.Field && paxInfo.PassengerSummaryY[key] > 0) {\r\n retVal = true;\r\n break;\r\n }\r\n }\r\n for (var key in paxInfo.PassengerSummaryX) {\r\n if (key === memoCriterion.Field && paxInfo.PassengerSummaryY[key] > 0) {\r\n retVal = true;\r\n break;\r\n }\r\n }\r\n return retVal;\r\n }\r\n\r\n /**\r\n * Check if the zone is valid\r\n * @memberof MemoFactory\r\n * @param {CriteriaZone} Zone from MemoCriteria\r\n * @param {FlightZones} List of Zones from flight\r\n */\r\n function isValidZone(CriteriaZone, FlightZones) {\r\n if (!CriteriaZone || CriteriaZone.Type != \"Zone\" || !FlightZones || FlightZones.length == 0) {\r\n return false;\r\n } else {\r\n // some is equivalent to Any()\r\n var zoneExist = FlightZones.some(function (item) {\r\n return item.Title.toUpperCase() == CriteriaZone.Field.toUpperCase() && item.Class.toUpperCase() == CriteriaZone.FieldOptional.toUpperCase();\r\n });\r\n return zoneExist;\r\n }\r\n }\r\n\r\n /**\r\n * Get Stored Memos \r\n * @memberof MemoFactory\r\n * @param {function} callback The callback function\r\n */\r\n function getStoredMemosIds(callback) {\r\n getMemosFromStorage(function (memos) {\r\n var memoIds = [];\r\n for (var i = 0; i < memos.length; i++) {\r\n var memoIdRead = {\r\n Id: memos[i].Id,\r\n ReadDt: memos[i].ReadDt\r\n }\r\n\r\n memoIds.push(memoIdRead);\r\n }\r\n callback(memoIds);\r\n });\r\n }\r\n\r\n /**\r\n * set memos from server api \r\n * @memberof MemoFactory\r\n * @param {array} memos The memos \r\n * @param {array} memoIdsToSend The old memos of the storage\r\n * @param {string} lastSyncDate The last Sync Date \r\n */\r\n function setMemosFromServer(memos, memoIdsToSend, lastSyncDate) {\r\n if (!memoIdsToSend || memoIdsToSend.length == 0 || !lastSyncDate) {\r\n setMemosToStorage(memos);\r\n } else {\r\n for (var j = 0; j < memos.length; j++) {\r\n var IsMemoIncluded = false;\r\n\r\n for (var h = 0; h < memoIdsToSend.length; h++) {\r\n if (memos[j].Id == memoIdsToSend[h].Id) {\r\n IsMemoIncluded = true;\r\n break;\r\n }\r\n }\r\n\r\n if (IsMemoIncluded) {\r\n memos[j].IsUpdated = true;\r\n memos[j].IsNew = false;\r\n saveOneMemoToStorage(memos[j]);\r\n } else {\r\n memos[j].IsNew = true;\r\n memos[j].IsUpdated = false;\r\n addMemoToStorage(memos[j]);\r\n }\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Get Unread Memos \r\n * @memberof MemoFactory\r\n */\r\n function getUnreadMemos(callback) {\r\n getNotHiddenMemos(function (memos) {\r\n if (!memos)\r\n return [];\r\n\r\n var arrayLength = memos.length;\r\n var result = [];\r\n\r\n for (var i = 0; i < arrayLength; i++) {\r\n if (!memos[i].ReadDt) {\r\n result.push(memos[i]);\r\n }\r\n }\r\n callback(result);\r\n });\r\n }\r\n\r\n /**\r\n * Get Count of Unread Mandatory Memos\r\n * @memberof MemoFactory\r\n */\r\n function getMandatoryUnreadMemos(callback) {\r\n getNotHiddenMemos(function (memos) {\r\n if (!memos)\r\n return [];\r\n\r\n var result = [];\r\n var arrayLength = memos.length;\r\n\r\n for (var i = 0; i < arrayLength; i++) {\r\n if (!memos[i].ReadDt && memos[i].IsMandatory) {\r\n result.push(memos[i]);\r\n }\r\n }\r\n callback(result);\r\n });\r\n }\r\n\r\n /**\r\n * Flags Ground Duties if they have at least one unread memo\r\n * @memberof MemoFactory\r\n */\r\n function markGroundDutiesUnread() {\r\n getAllUnreadGroundDutyMemos(function (groundDutyMemos) {\r\n\r\n var groundDuties = GroundDutyFactory.getGroundDutiesFromStorage();\r\n\r\n if (groundDuties != null) {\r\n for (var i = 0; i < groundDuties.length; i++) {\r\n groundDuties[i].Unread = false;\r\n\r\n //check if this ground duty has any unread ground duty memo\r\n var fromDutyDate = new Date(groundDuties[i].DutyDate).getTime();\r\n var toDutyDate = new Date(groundDuties[i].DutyDate).getTime();\r\n\r\n for (var j = 0; j < groundDutyMemos.length; j++) {\r\n if (new Date(groundDutyMemos[j].ValidFrom).getTime() <= fromDutyDate && new Date(groundDutyMemos[j].ValidTo).getTime() >= toDutyDate) {\r\n for (var z = 0; z < groundDutyMemos[j].MemoCriteria.length; z++) {\r\n var item = groundDutyMemos[j].MemoCriteria[z];\r\n if ((item.Field == groundDuties[i].DutyNo || item.Field == groundDuties[i].GroundDutyNo)) {\r\n groundDuties[i].Unread = true;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n GroundDutyFactory.setGroundDutiesToStorage(groundDuties);\r\n }\r\n });\r\n }\r\n\r\n\r\n /**\r\n * Exclude hidden memos from collection\r\n * @memberof MemoFactory\r\n */\r\n function getNotHiddenMemos(callback) {\r\n getMemosFromStorage(function (memos) {\r\n var result = [];\r\n if (memos) {\r\n result = memos.filter(function (memo) {\r\n return !memo.IsHidden;\r\n });\r\n }\r\n callback(result);\r\n });\r\n }\r\n\r\n return service;\r\n }\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('MemoImagesFactory', MemoImagesFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name MemoImagesFactory\r\n * @description \r\n * Add, Update, Delete and Get Memo's Images.\r\n * @ngInject\r\n */ \r\nfunction MemoImagesFactory(GenericService, IndexedDBService) {\r\n\r\n /**\r\n * Initialize the MemoImage\r\n * @memberof MemoImagesFactory\r\n */\r\n\t\tfunction MemoImage() {\r\n\t\t\tthis.Id = null;\r\n\t\t}\r\n\r\n\t\tvar objType = 'MemoImages';\r\n\t\tvar objCallback = MemoImage;\r\n\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tgetMemoImagesFromStorage : getMemoImagesFromStorage,\r\n\t\t\tsetMemoImagesToStorage : setMemoImagesToStorage,\r\n\t\t\tsaveOneMemoImageToStorage : saveOneMemoImageToStorage,\r\n\t\t\taddMemoImageToStorage : addMemoImageToStorage,\r\n\t\t\tdeleteMemoImageFromStorage : deleteMemoImageFromStorage,\r\n\t\t\tdeleteMemoImageByMemoId : deleteMemoImageByMemoId,\r\n\t\t\tsetImagesToServer : setImagesToServer,\r\n\t\t\tclearMemoImagesFromStorage : clearMemoImagesFromStorage,\r\n getMemoImagesByIndex : getMemoImagesByIndex,\r\n info : info\r\n\t\t};\r\n\t\t\t\t\r\n /**\r\n * Get Memo Images \r\n * @memberof MemoImagesFactory\r\n * @param {function} callback \r\n */\r\n\t\tfunction getMemoImagesFromStorage(callback) {\r\n\t\t\t//return GenericService.list(objType,objCallback);\r\n\t\t\tIndexedDBService.getAll(objType).then(function(results){\r\n\t\t\t\tcallback(results);\r\n\t\t\t});\r\n\t\t};\r\n\r\n /**\r\n * Get Memo Images by memo Id\r\n * @memberof MemoImagesFactory\r\n * @param {number} id Memo Id \r\n * @param {function} callback \r\n */\r\n function getMemoImagesByIndex(id,callback) {\r\n\t\t\t//return GenericService.list(objType,objCallback);\r\n\t\t\tIndexedDBService.getByIndex(objType,'memoId',id).then(function(results){\r\n\t\t\t\tcallback(results);\r\n\t\t\t});\r\n\t\t};\r\n\r\n /**\r\n * Add Memo Images \r\n * @memberof MemoImagesFactory\r\n * @param {array} MemoImages List of memo images\r\n */\r\n\t\tfunction setMemoImagesToStorage(MemoImages) {\r\n\t\t\t//GenericService.saveAll(Memos,objType,objCallback);\r\n\t\t\tIndexedDBService.addAll(objType, MemoImages);\r\n\t\t};\r\n\r\n function info(){\r\n IndexedDBService.info(objType);\r\n }\r\n\r\n\r\n /**\r\n * Update Memo Images \r\n * @memberof MemoImagesFactory\r\n * @param {object} MemoImage a memo image\r\n */\r\n\t\tfunction saveOneMemoImageToStorage(MemoImage){\r\n\t\t\tIndexedDBService.put(objType, MemoImage);\r\n\t\t};\r\n\r\n /**\r\n * Add Memo Image\r\n * @memberof MemoImagesFactory\r\n * @param {object} MemoImage a memo image\r\n */\r\n\t\tfunction addMemoImageToStorage(MemoImage){\r\n\t\t\tIndexedDBService.add(objType, MemoImage);\r\n\t\t};\r\n\r\n /**\r\n * Delete Memo Image\r\n * @memberof MemoImagesFactory\r\n * @param {number} MemoImageId a memo image Id\r\n */\r\n\t\tfunction deleteMemoImageFromStorage(MemoImageId){\r\n\t\t\tIndexedDBService.remove(objType, MemoImageId);\r\n\t\t};\r\n \r\n /**\r\n * Delete Memo Image by MemoId\r\n * @memberof MemoImagesFactory\r\n * @param {number} MemoId a memo Id\r\n */\r\n function deleteMemoImageByMemoId(MemoId){\r\n\t\t\tIndexedDBService.removeByIndex(objType,'memoId', MemoId);\r\n\t\t};\r\n \r\n /**\r\n * Set Memo Image by api call\r\n * @memberof MemoImagesFactory\r\n * @param {array} images List of memo images\r\n */ \r\n function setImagesToServer(images){\r\n for(var i=0;i 0) {\r\n\t\t\t\t\tmemos.push(\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\tCategory: memo.Category,\r\n\t\t\t\t\t\t\tmemoList: [memo],\r\n\t\t\t\t\t\t\tfilterList: [memo]\r\n\t\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t\telse if (memos.filter(function (e) { return e.Category == memo.Category }).length > 0) {\r\n\r\n\t\t\t\t\tmemos.filter(function (object) {\r\n\t\t\t\t\t\tif (object.Category == memo.Category) {\r\n\t\t\t\t\t\t\treturn object;\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t})[0].memoList.push(memo);\r\n\t\t\t\t\tmemos.filter(function (object) {\r\n\t\t\t\t\t\tif (object.Category == memo.Category) {\r\n\t\t\t\t\t\t\treturn object;\r\n\t\t\t\t\t\t};\r\n\t\t\t\t\t})[0].memoList.dynamicSort(\"LastUpdated\", false);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t(function changeFlags() {\r\n\t\t\t\t\tangular.forEach(memoList[i].MemoCriteria, function (criteria) {\r\n\t\t\t\t\t\tif (criteria.Country || criteria.Type == \"Country\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasCountry = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.FlightNo || criteria.Type == \"FlightNo\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasFlightNo = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.Airport || criteria.Type == \"Airport\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasAirport = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.RouteStart || criteria.Type == \"RouteStart\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasRoute = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.AcType || criteria.Type == \"AcType\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasAcType = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.Zone || criteria.Type == \"Zone\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasZone = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.AcRegistration || criteria.Type == \"AcRegistration\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasAcRegistration = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.Type == \"SsrCode\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasSsrCode = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.Type == \"TrainingId\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasTrainingIndicator = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.Type == \"European\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasEuropean = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.Type == \"Schengen\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasSchengen = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (criteria.Type == \"GroundDutyCode\" && criteria.Field) {\r\n\t\t\t\t\t\t\t$scope.hasGroundDuties = true;\r\n\t\t\t\t\t\t\t$scope.hasNone = false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t})\r\n\t\t\t\t})();\r\n\t\t\t}\r\n\t\t\treturn memos.dynamicSort(\"Category\", true);\r\n\t\t}\r\n\r\n\t\tfunction select(category) {\r\n\t\t\tselectMemoCategory(category);\r\n\t\t\ttoggleSidePanel();\r\n\t\t}\r\n\r\n\t\tfunction selectMemoCategory(category) {\r\n\t\t\tvar memosByCategory = $scope.memosByCategory;\r\n\t\t\tfor (var i = 0; i < memosByCategory.length; i++) {\r\n\t\t\t\tif (memosByCategory[i].Category == category.Category) {\r\n\t\t\t\t\t$scope.selected = memosByCategory[i];\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction showhideDescr() {\r\n\t\t\t$scope.toShowBody = !$scope.toShowBody\r\n\t\t\t$scope.toShowAppliesTo = !$scope.toShowAppliesTo\r\n\t\t}\r\n\r\n\t\tfunction toggleSidePanel() {\r\n\t\t\t$scope.shownSideMenu = !$scope.shownSideMenu;\r\n\t\t}\r\n\r\n\t\t//Pagination\r\n\t\t$scope.pageOptions = [\r\n\t\t\t{ name: '5', value: '5' },\r\n\t\t\t{ name: '8', value: '8' },\r\n\t\t\t{ name: '15', value: '15' },\r\n\t\t\t{ name: '30', value: '30' },\r\n\t\t\t{ name: '50', value: '50' }\r\n\t\t];\r\n\r\n\t\t$scope.viewby = $scope.pageOptions[1].value;\r\n\t\t$scope.currentPage = 1;\r\n\t\t$scope.itemsPerPage = $scope.viewby;\r\n\t\t$scope.maxSize = 5; //Number of pager buttons to show\r\n\t\t$scope.setPage = setPage;\r\n\t\t$scope.setItemsPerPage = setItemsPerPage;\r\n\r\n\t\t//Controller functions\r\n\r\n\t\t/**\r\n\t\t* Set pagination page number\r\n\t\t* @memberof MemosCtrl\r\n\t\t* @param {number} pageNo list page number\r\n\t\t*/\r\n\t\tfunction setPage(pageNo) {\r\n\t\t\t$scope.currentPage = pageNo;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Set items per page \r\n\t\t * @memberof MemosCtrl\r\n\t\t * @param {number} num the Number of items to show per page\r\n\t\t */\r\n\t\tfunction setItemsPerPage(num) {\r\n\t\t\t$scope.itemsPerPage = num;\r\n\t\t\t$scope.currentPage = 1; //reset to first paghe\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * View Selected Memo\r\n\t\t * @memberof MemosCtrl\r\n\t\t * @param {object} memo The selected Memo\r\n\t\t */\r\n\t\tfunction openMemo(memo) {\r\n\t\t\tvar modalInstance = $uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgMemo.html',\r\n\t\t\t\tcontroller: 'MemoModalCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tmemo: function () {\r\n\t\t\t\t\t\treturn memo;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\tmodalInstance.result.then(function () {\r\n\t\t\t\tif (memo.ReadDt == null) {\r\n\t\t\t\t\tmemo.ReadDt = new Date();\r\n\t\t\t\t\tMemoFactory.saveOneMemoToStorage(memo);\r\n\r\n\t\t\t\t\t//check if memo is connected to a ground duty\r\n\t\t\t\t\tfor (var i = 0; i < memo.MemoCriteria.length; i++) {\r\n\t\t\t\t\t\tvar item = memo.MemoCriteria[i];\r\n\t\t\t\t\t\tif (item.QueryType == \"GroundDutyCode\") {\r\n\t\t\t\t\t\t\tMemoFactory.markGroundDutiesUnread();\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tsearchMemos($scope.searchText, '');\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\tfunction redirectModal() {\r\n\t\t\tvar modalInstance = $uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgCalendarRedirect.html',\r\n\t\t\t\tcontroller: 'CalendarRedirectModalCtrl',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tsize: 'md',\r\n\t\t\t\tkeyboard: false\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Search the selected text In Memo Title and body\r\n\t\t * @memberof MemosCtrl\r\n\t\t * @param {string} text The desired search text\r\n\t\t */\r\n\t\tfunction searchMemos(text, filter) {\r\n\t\t\tif (filter != '') {\r\n\t\t\t\t$scope.radioModel = filter;\r\n\t\t\t}\r\n\t\t\tvar filteredMemos = [];\r\n\t\t\tvar searchText = text.toLowerCase();\r\n\t\t\tvar newList = $scope.memos;\r\n\r\n\t\t\tfor (var i = 0; i < newList.length; i++) {\r\n\t\t\t\tif ($scope.radioModel == 'General') {\r\n\t\t\t\t\tif (newList[i].MemoCriteria && newList[i].MemoCriteria.length > 0) {\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse if ($scope.radioModel == 'Unread') {\r\n\t\t\t\t\tif (newList[i].ReadDt) {\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse if ($scope.radioModel == 'Mandatory') {\r\n\t\t\t\t\tif (!newList[i].IsMandatory) {\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse if ($scope.radioModel == 'UnreadMandatory') {\r\n\t\t\t\t\tif (newList[i].ReadDt || !newList[i].IsMandatory) {\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\telse if ($scope.radioModel == 'Monthly') {\r\n\r\n\t\t\t\t\tvar diffTime = Math.abs(new Date() - moment.utc(newList[i].LastUpdated).utc().toDate());\r\n\t\t\t\t\tvar diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));\r\n\r\n\t\t\t\t\tif (diffDays >= 30) {\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar memoTitle = newList[i].Title.toLowerCase();\r\n\r\n\t\t\t\tif (memoTitle.indexOf(searchText) > -1) {\r\n\t\t\t\t\tfilteredMemos.push(newList[i]);\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tvar memosByCategory = MemosByCategories(filteredMemos);\r\n\t\t\t$scope.memosByCategory = memosByCategory;\r\n\r\n\t\t\tvar showAllCategory = {\r\n\t\t\t\tCategory: 'Show All',\r\n\t\t\t\tmemoList: filteredMemos,\r\n\t\t\t\tfilterList: filteredMemos\r\n\t\t\t}\r\n\r\n\t\t\tif (searchText != null && searchText != undefined && searchText.length > 0) {\r\n\t\t\t\tmemosByCategory.push(showAllCategory);\r\n\t\t\t}\r\n\r\n\t\t\tsearchResultsCount();\r\n\r\n\t\t\tif (!memosByCategory || !memosByCategory.length) {\r\n\t\t\t\t$scope.selected == null\t\t//selected could be null if search didn't return any results\r\n\t\t\t\tif ($scope.radioModel == 'UnreadMandatory') {\t//all mandatory memos were read\r\n\t\t\t\t\t// $scope.radioModel = 'All';\r\n\t\t\t\t\t// searchMemos(searchText, '');\r\n\t\t\t\t\tredirectModal();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse if ($scope.selected == null) { //search now returns results\r\n\t\t\t\t$scope.selected = memosByCategory[0];\r\n\t\t\t}\r\n\t\t\tif (searchText != null && searchText != undefined && searchText.length > 0) {\r\n\t\t\t\t$scope.selected = showAllCategory;\r\n\t\t\t}\r\n\r\n\t\t\tvar select = false;\r\n\r\n\t\t\tfor (var i = 0; i < memosByCategory.length; i++) {\r\n\t\t\t\tif ($scope.selected.Category == memosByCategory[i].Category) {\r\n\t\t\t\t\tselectMemoCategory(memosByCategory[i]);\r\n\t\t\t\t\tselect = true;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!select) $scope.selected = memosByCategory[0];\r\n\t\t}\r\n\t}\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('MessageCtrl',MessageCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name MessageCtrl\r\n * @description \r\n * Manages the messages View\r\n * @ngInject\r\n */\r\nfunction MessageCtrl($scope, MessageFactory, $filter, $sce) {\r\n\r\n\t\tvar messages = []\r\n\r\n $scope.messages = MessageFactory.getMessagesFromStorage();\r\n messages = $scope.messages;\r\n\r\n\t\t\r\n\t\t$scope.messageCount = messages.length;\r\n\t\t$scope.state = 'messages';\r\n\t\t$scope.openMessage = openMessage;\r\n\t\t$scope.isEnabled = false;\r\n\t\t$scope.setupView = setupView;\r\n $scope.trustAsHtml = trustAsHtml;\r\n\r\n /**\r\n * Trust this html style text\r\n * @memberof MessageCtrl\r\n * @param {string} body The body message\r\n */\r\n function trustAsHtml(body){\r\n \r\n return $sce.trustAsHtml(body);\r\n }\r\n\t\t\r\n /**\r\n * Setup the message View\r\n * @memberof MessageCtrl\r\n * @param {boolean} isEnabled Show only unread messages\r\n */\r\n\t\tfunction setupView(isEnabled) {\r\n\t\t\t$scope.messages = $filter('messageFilter')(messages, isEnabled);\r\n\t\t}\r\n\r\n /**\r\n * View Selected message\r\n * @memberof MessageCtrl\r\n * @param {object} message The selected Message\r\n */\r\n\t\tfunction openMessage(message) {\r\n\t\t\tif (message.ReadDt == null) {\r\n\t\t\t\tMessageFactory.markReaden(message.Id);\r\n\t\t\t\tmessage.ReadDt = new Date();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.filter('messageFilter',messageFilter) \r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc filter\r\n * @name messageFilter\r\n * @description \r\n * Filters messages in order to show only the unread.\r\n * @ngInject\r\n */\r\nfunction messageFilter() {\r\n\t\treturn function(input, isEnable) {\r\n\t\t\tif (isEnable) {\r\n\t\t\t\tvar result = [];\r\n\t\t\t\tfor (var i = 0; i < input.length; i++) {\r\n\t\t\t\t\tif (input[i].ReadDt == null) {\r\n\t\t\t\t\t\tresult.push(input[i]);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\treturn result;\r\n\t\t\t} else {\r\n\t\t\t\treturn input;\r\n\t\t\t}\r\n\t\t};\r\n\t}\r\n\r\n })();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('MessageModalCtrl', MessageModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name MessageModalCtrl\r\n * @description \r\n * Manages the message Modal\r\n * @ngInject\r\n */\r\nfunction MessageModalCtrl($scope, message, $uibModalInstance, $sce) {\r\n \r\n $scope.message = message;\r\n $scope.cancel = cancel;\r\n\r\n $scope.messageBody = $sce.trustAsHtml(message.Body);\r\n \r\n /**\r\n * Close the modal\r\n * @memberof MemoModalCtrl\r\n */\r\n\t\tfunction cancel() {\r\n\t\t\t$uibModalInstance.close('close');\r\n\t\t}\r\n\t}\r\n\r\n\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.factory('CustomerEventFactory', CustomerEventFactory);\r\n\t/**\r\n\t* @memberof CabinReports\r\n\t* @ngdoc factory\r\n\t* @name CustomerEventFactory\r\n\t* @description \r\n\t* Add, Update, Delete and Get Passenger Incidents\r\n\t* @ngInject\r\n\t*/\r\n\tfunction CustomerEventFactory(GenericService) {\r\n\r\n\t\tvar objType = 'CustomerEvents';\r\n\t\tvar objCallback = CustomerEvent;\r\n\r\n\t\t/**\r\n\t\t * Initialize the Passenger Incident\r\n\t\t * @memberof CustomerEventFactory\r\n\t\t */\r\n\t\tfunction CustomerEvent() {\r\n\t\t\tthis.GetId = GetId;\r\n\t\t\tthis.Synced = false;\r\n\t\t}\r\n\r\n\t\tvar service = {\r\n\t\t\tgetCustomerEventsFromStorage: getCustomerEventsFromStorage,\r\n\t\t\tsetCustomerEventToStorage: setCustomerEventToStorage,\r\n\t\t\tsetCustomerEventsToStorage: setCustomerEventsToStorage,\r\n\t\t\tgetCustomerEventsByFlightId: getCustomerEventsByFlightId,\r\n\t\t\tgroupFlightCustomerEventsByPassenger: groupFlightCustomerEventsByPassenger,\r\n\t\t\tgetFlightCustomerEvents: getFlightCustomerEvents,\r\n\t\t\tupdateCustomerEvent: updateCustomerEvent,\r\n\t\t\tsaveCustomerEvent: saveCustomerEvent,\r\n\t\t\tremoveCustomerEvent: removeCustomerEvent,\r\n\t\t\tgetUnsyncedCustomerEvents: getUnsyncedCustomerEvents,\r\n\t\t\tdeleteOldCustomerEvents: deleteOldCustomerEvents\r\n\r\n\t\t};\r\n\r\n\t\tfunction GetId() {\r\n\t\t\treturn this.LocalId;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Save all Customer Events\r\n\t\t * @param {array} objList \r\n\t\t */\r\n\t\tfunction setCustomerEventsToStorage(objList) {\r\n\t\t\tGenericService.saveAll(objList, objType);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Add or Update a Customer Event\r\n\t\t * @param {object} customerEvent \r\n\t\t */\r\n\t\tfunction setCustomerEventToStorage(customerEvent) {\r\n\t\t\tvar flightCustomerEvents = getFlightCustomerEvents(customerEvent.FlightId, customerEvent.UCI);\r\n\r\n\t\t\tif (flightCustomerEvents) {\r\n\t\t\t\tvar incident = flightCustomerEvents.find(x => x.LocalId == customerEvent.LocalId);\r\n\r\n\t\t\t\tif (incident) {\r\n\t\t\t\t\tupdateCustomerEvent(customerEvent);\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tsaveCustomerEvent(customerEvent);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tsaveCustomerEvent(customerEvent);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Get all passenger events of a flight\r\n\t\t * @param {number} flightId \r\n\t\t */\r\n\t\tfunction getCustomerEventsByFlightId(flightId) {\r\n\t\t\tvar allIncidents = getCustomerEventsFromStorage();\r\n\t\t\tvar flightIncidents = allIncidents.filter(x => x.FlightId == flightId);\r\n\t\t\treturn flightIncidents;\r\n\t\t};\r\n\r\n\t\t/**\r\n\t\t * Group all customer events of a flight by passenger\r\n\t\t * @param {number} flightId \r\n\t\t */\r\n\t\tfunction groupFlightCustomerEventsByPassenger(flightId) {\r\n\t\t\tvar oneStopShopPassengers = [];\r\n\t\t\tvar allIncidents = getCustomerEventsFromStorage();\r\n\t\t\tvar flightIncidents = allIncidents.filter(x => x.FlightId == flightId);\r\n\r\n\t\t\tvar oneStopShopPassengerIds = [...new Set(flightIncidents.map(x => x.UCI))];\r\n\r\n\t\t\toneStopShopPassengerIds.forEach(function (id) {\r\n\t\t\t\tvar incident = flightIncidents.find(x => x.UCI == id);\r\n\t\t\t\tvar passenger = {\r\n\t\t\t\t\tUCI: incident.UCI,\r\n\t\t\t\t\tGivenName: incident.GivenName,\r\n\t\t\t\t\tSurname: incident.Surname,\r\n\t\t\t\t\tSeatNo: incident.SeatNo,\r\n\t\t\t\t\tOneStopShopEvents: []\r\n\t\t\t\t};\r\n\r\n\t\t\t\tflightIncidents.filter(x => x.UCI == id).forEach(function (incident) {\r\n\t\t\t\t\tvar event = {\r\n\t\t\t\t\t\tToolkitItemId: incident.ToolkitItemId,\r\n\t\t\t\t\t\tTreatmentId: incident.TreatmentId,\r\n\t\t\t\t\t\tNPS: incident.NPS,\r\n\t\t\t\t\t\tSynced: incident.Synced\r\n\t\t\t\t\t};\r\n\t\t\t\t\tpassenger.OneStopShopEvents.push(event);\r\n\t\t\t\t});\r\n\r\n\t\t\t\toneStopShopPassengers.push(passenger);\r\n\t\t\t});\r\n\r\n\t\t\treturn oneStopShopPassengers;\r\n\t\t};\r\n\r\n\t\t/**\r\n\t\t * Get all customer events\r\n\t\t */\r\n\t\tfunction getCustomerEventsFromStorage() {\r\n\t\t\treturn GenericService.list(objType, objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Get events for a specific passenger in a specific flight\r\n\t\t * @param {number} flightId \r\n\t\t * @param {number} uci \r\n\t\t */\r\n\t\tfunction getFlightCustomerEvents(flightId, uci) {\r\n\t\t\tvar flightIncidents = getCustomerEventsByFlightId(flightId);\r\n\t\t\tvar customerEvents = flightIncidents.filter(x => x.UCI == uci);\r\n\t\t\treturn customerEvents;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Update a customer event (Search by FlightId-ToolkitItemId-UCI)\r\n\t\t * @param {object} customerEvent \r\n\t\t */\r\n\t\tfunction updateCustomerEvent(customerEvent) {\r\n\t\t\tGenericService.save(customerEvent, objType, objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Create a new customer event\r\n\t\t * @param {object} customerEvent \r\n\t\t */\r\n\t\tfunction saveCustomerEvent(customerEvent) {\r\n\t\t\tGenericService.add(customerEvent, objType, objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Remove customer event from storage \r\n\t\t * @param {object} customerEvent \r\n\t\t */\r\n\t\tfunction removeCustomerEvent(customerEventId) {\r\n\t\t\tGenericService.remove(customerEventId, objType, objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Get Customers Events that have not yet been Synced\r\n\t\t */\r\n\t\tfunction getUnsyncedCustomerEvents() {\r\n\t\t\tvar unsyncedEvents = getCustomerEventsFromStorage().filter(x => !x.Synced);\r\n\r\n\t\t\t//Give each event a temporary Id\r\n\t\t\tvar tempId = 1;\r\n\t\t\tunsyncedEvents.forEach(function (event) {\r\n\t\t\t\tevent.TemporaryId = tempId;\r\n\t\t\t\ttempId++;\r\n\r\n\t\t\t\t//No Treatment Id needs to be sent as null\r\n\t\t\t\tif (event.TreatmentId == -1) {\r\n\t\t\t\t\tevent.TreatmentId = null;\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t\treturn unsyncedEvents;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Deletes Customer Events that are older than 2 days\r\n\t\t * @memberof DataCleanerFactory\r\n\t\t */\r\n\t\tfunction deleteOldCustomerEvents() {\r\n\t\t\tvar customerEvents = getCustomerEventsFromStorage();\r\n\t\t\tvar fromDate = new Date();\r\n\t\t\tfromDate.setDate(fromDate.getDate() - 5);\r\n\t\t\tcustomerEvents = customerEvents.filter(x => x != null && x.FlightDate >= fromDate);\r\n\t\t\tsetCustomerEventsToStorage(customerEvents);\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.factory('CustomerEventHistoryFactory', CustomerEventHistoryFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CustomerEventHistoryFactory\r\n * @description \r\n * Add, Update, Delete and Get History Customer Events for OneStopShop\r\n * @ngInject\r\n */\r\n\tfunction CustomerEventHistoryFactory(GenericService) {\r\n\r\n\t\tvar objType = 'HistoryEvents';\r\n\t\tvar objCallback = HistoryEvent;\r\n\r\n /**\r\n * Initialize the History Event\r\n * @memberof CustomerEventHistoryFactory\r\n */\r\n\t\tfunction HistoryEvent() {\r\n\t\t\tthis.GetId = GetId;\r\n\t\t}\r\n\r\n\t\tvar service = {\r\n\t\t\tsetHistoryEventsToStorage : setHistoryEventsToStorage,\r\n\t\t\tgetHistoryEventsFromStorage : getHistoryEventsFromStorage,\r\n\t\t\tgetPassengerHistory : getPassengerHistory,\r\n\t\t\trefreshPassengerHistory : refreshPassengerHistory,\r\n\t\t\tdeleteOldHistoryEvents: deleteOldHistoryEvents\r\n\t\t};\r\n\r\n\t\t\r\n\t\tfunction GetId(){\r\n\t\t\treturn this.FlightId;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Save all History Events\r\n\t\t * @param {array} objList \r\n\t\t */\r\n\t\tfunction setHistoryEventsToStorage(objList) {\r\n\t\t\tGenericService.saveAll(objList,objType);\r\n\t\t}\r\n\t\t\r\n\t\t/**\r\n\t\t * Get all History Events\r\n\t\t */\r\n\t\tfunction getHistoryEventsFromStorage(){\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Get History Events of a specific passenger\r\n\t\t * @param {objects} passenger \r\n\t\t */\r\n\t\tfunction getPassengerHistory(passenger){\r\n\t\t\tvar passengerFqtv = passenger.Fqtv ? passenger.Fqtv.Number : null;\r\n\t\t\tvar passengerUci = passenger.UCI;\r\n\r\n\t\t\t//Filter passenger by FQTV and UCI\r\n\t\t\tvar passengerHistoryEvents = getHistoryEventsFromStorage().filter(p => (p.FQTVNumber && passengerFqtv && p.FQTVNumber == passengerFqtv) || p.UCI == passengerUci);\r\n\r\n\t\t\treturn passengerHistoryEvents;\r\n\t\t}\r\n\t\t\r\n\t\tfunction refreshPassengerHistory(flightHistoryEvents){\r\n\t\t\tvar history = getHistoryEventsFromStorage();\r\n\r\n\t\t\tflightHistoryEvents.forEach(function(event){\r\n\t\t\t\tvar historyEvent = history.find(x => x.ToolkitItem.Id == event.ToolkitItem.Id && x.UCI == event.UCI && x.FlightNo == event.FlightNo && x.Departure == event.Departure && x.FlightDate == event.FlightDate);\r\n\t\t\t\tif(!historyEvent){\r\n\t\t\t\t\tGenericService.add(event, objType, objCallback);\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t /**\r\n * Deletes HistoryEvents that are older than 2 days\r\n * @memberof DataCleanerFactory\r\n */\r\n\t\t function deleteOldHistoryEvents(){\r\n\t\t\tvar historyEvents = getHistoryEventsFromStorage();\r\n\t\t\tvar fromDate = new Date();\r\n fromDate.setDate(fromDate.getDate() - 5);\r\n\t\t\thistoryEvents = historyEvents.filter(x => x != null && x.FlightDate >= fromDate);\r\n\t\t\tsetHistoryEventsToStorage(historyEvents);\r\n }\r\n\r\n\t\treturn service;\r\n\t}\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('history', history);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name history\r\n * @restrict E\r\n * @description\r\n * Implementation of history\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function history(ToolkitFactory, CustomerEventHistoryFactory) {\r\n function link(scope) {\r\n scope.history = CustomerEventHistoryFactory.getPassengerHistory(scope.passenger);\r\n }\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/OneStopShop/history.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('onestopshopEvent', onestopshopEvent);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name onestopshopEvent\r\n * @restrict E\r\n * @description\r\n * Implementation of onestopshopEvent\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function onestopshopEvent() {\r\n function link(scope) {\r\n scope.ToolkitItem = scope.customerEvent.ToolkitItem;\r\n scope.Treatment = scope.customerEvent.Treatment;\r\n }\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/OneStopShop/onestopshopEvent.tpl.html',\r\n scope: {customerEvent: \"=\"},\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('ToolkitFactory', ToolkitFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ToolkitFactory\r\n * @description \r\n * Add, Update, Delete and Get Memos.\r\n * @ngInject\r\n */\r\n function ToolkitFactory(IndexedDBService) {\r\n\r\n /**\r\n * Initialize the Toolkit Item\r\n * @memberof ToolkitFactory\r\n */\r\n function ToolkitItem() {\r\n this.Id = null;\r\n }\r\n\r\n var objType = 'ToolkitItems';\r\n var objCallback = ToolkitItem;\r\n\r\n var service = {\r\n setToolkitItemsFromServer : setToolkitItemsFromServer,\r\n getToolkitItemsFromStorage : getToolkitItemsFromStorage,\r\n setToolkitItemsToStorage : setToolkitItemsToStorage,\r\n saveToolkitItemToStorage : saveToolkitItemToStorage,\r\n addToolkitItemToStorage : addToolkitItemToStorage\r\n };\r\n\r\n /**\r\n * Set ToolkitItems from server API \r\n * @memberof ToolkitFactory\r\n * @param {array} toolkitItems ToolkitItems Object\r\n */\r\n function setToolkitItemsFromServer(toolkitItems) {\r\n\r\n //Manually add 'No Treatment' option\r\n toolkitItems.forEach(function(item){\r\n item.Treatments.push({\r\n Id: -1,\r\n PaxCategory: 0,\r\n Title: \"No Treatment\",\r\n Description: \"\",\r\n Type: \"\",\r\n Comments: null,\r\n ToolkitItemId: item.Id,\r\n });\r\n });\r\n\r\n getToolkitItemsFromStorage(function(localToolkitItems){\r\n // No Toolkit Items found - Save All Incoming\r\n if (!localToolkitItems || localToolkitItems.length == 0) {\r\n setToolkitItemsToStorage(toolkitItems);\r\n } \r\n else \r\n {\r\n for (var j = 0; j < toolkitItems.length; j++) {\r\n var isToolkitItemIncluded = false;\r\n\r\n for (var h = 0; h < localToolkitItems.length; h++) {\r\n if (toolkitItems[j].Id == localToolkitItems[h].Id) {\r\n isToolkitItemIncluded = true;\r\n break; \r\n }\r\n } \r\n \r\n //Update\r\n if (isToolkitItemIncluded) {\r\n saveToolkitItemToStorage(toolkitItems[j]);\r\n } \r\n //Add \r\n else {\r\n addToolkitItemToStorage(toolkitItems[j]);\r\n }\r\n }\r\n \r\n localToolkitItems.filter(x=> !toolkitItems.some(z=>z.Id == x.Id)).forEach(function(item){\r\n IndexedDBService.remove(objType,item.Id)\r\n })\r\n } \r\n })\r\n }\r\n\r\n /**\r\n * Get Toolkit Items\r\n * @memberof ToolkitFactory\r\n * @param {*} callback \r\n */\r\n function getToolkitItemsFromStorage(callback) {\r\n IndexedDBService.getAll(objType).then(function (results) {\r\n callback(results);\r\n });\r\n }\r\n\r\n /**\r\n * Set Toolkit Items\r\n * @memberof ToolkitFactory\r\n * @param {array} ToolkitItems A list of Toolkit Items to set to indexedDB\r\n */\r\n function setToolkitItemsToStorage(ToolkitItems, callback, errorCallback) {\r\n IndexedDBService.addAll(objType, ToolkitItems).then(callback).catch(errorCallback);;\r\n };\r\n\r\n /**\r\n * Add Toolkit Item to Storage\r\n * @memberof ToolkitFactory\r\n * @param {object} ToolkitItem\r\n */\r\n function addToolkitItemToStorage(ToolkitItem, callback, errorCallback) {\r\n IndexedDBService.add(objType, ToolkitItem).then(callback).catch(errorCallback);\r\n };\r\n\r\n /**\r\n * Update Toolkit Item in Storage\r\n * @memberof ToolkitFactory\r\n * @param {object} ToolkitItem\r\n */\r\n function saveToolkitItemToStorage(ToolkitItem, callback, errorCallback) {\r\n IndexedDBService.put(objType, ToolkitItem).then(callback).catch(errorCallback);\r\n };\r\n\r\n return service;\r\n }\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('PassengerMealsCtrl', PassengerMealsCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name PassengerMealsCtrl\r\n * @description \r\n * Manages the Meal Library View\r\n * @ngInject\r\n */\r\n\r\n function PassengerMealsCtrl($scope, PassengerMealServiceFactory) {\r\n $scope.state = 'mealLibrary'; \r\n $scope.selectedService = null; \r\n $scope.selectedCycle = null; \r\n $scope.filteredMeals = []; \r\n $scope.isAllCyclesSelected = false;\r\n $scope.areAllMealsOpen = false;\r\n $scope.filteredServices = [];\r\n $scope.mealServiceSearch = '';\r\n\r\n $scope.selectService = selectService;\r\n $scope.filterByCycle = filterByCycle;\r\n $scope.toggleAllMeals = toggleAllMeals;\r\n $scope.searchMeals = searchMeals;\r\n $scope.toggleSidePanel = toggleSidePanel;\r\n $scope.filterMealServices = filterMealServices;\r\n\r\n PassengerMealServiceFactory.getPassengerMealServicesFromStorage(function (results) {\r\n $scope.passengerMeals = results;\r\n\r\n if ($scope.passengerMeals.length > 0) { \r\n $scope.selectService($scope.passengerMeals[0]); \r\n $scope.filteredServices = angular.copy($scope.passengerMeals); \r\n }\r\n });\r\n \r\n // Select a service and reset cycles and meals\r\n function selectService (service) {\r\n $scope.selectedService = service; // Set the selected service\r\n $scope.isAllCyclesSelected = false;\r\n\r\n // Clear the search field when selecting a new service\r\n $scope.searchText = '';\r\n\r\n // Check if the service has cycles and filter by the first cycle\r\n if (service.ServiceCycles && service.ServiceCycles.length > 0) {\r\n $scope.filterByCycle(service.ServiceCycles[0]);\r\n } else {\r\n $scope.selectedCycle = null; \r\n $scope.filteredMeals = [];\r\n }\r\n };\r\n\r\n // Filter meals by cycle when cycle radio button is selected\r\n function filterByCycle(cycle) {\r\n $scope.selectedCycle = cycle;\r\n $scope.isAllCyclesSelected = false; \r\n\r\n // Clear the search field\r\n $scope.searchText = '';\r\n\r\n $scope.filteredMeals = cycle.Meals.sort((a, b) => a.MealName.localeCompare(b.MealName));\r\n }; \r\n\r\n function filterMealServices() { \r\n if ($scope.mealServiceSearch && $scope.mealServiceSearch.length >= 2){\r\n $scope.filteredServices = $scope.passengerMeals.filter(service => \r\n service.ServiceName.toLowerCase().includes($scope.mealServiceSearch.toLowerCase())\r\n );\r\n } else{\r\n $scope.filteredServices = angular.copy($scope.passengerMeals);\r\n }\r\n }; \r\n\r\n // Toggle opening/closing all meals\r\n function toggleAllMeals() {\r\n $scope.areAllMealsOpen = !$scope.areAllMealsOpen;\r\n $scope.filteredMeals.forEach(function (meal) {\r\n meal.isInfoVisible = $scope.areAllMealsOpen;\r\n });\r\n };\r\n\r\n // Search meals within the selected service or cycle\r\n function searchMeals() {\r\n if ($scope.searchText && $scope.searchText.length >= 2) {\r\n var searchTextLower = $scope.searchText.toLowerCase();\r\n\r\n // If a specific cycle is selected, filter meals by that cycle\r\n if ($scope.selectedCycle) {\r\n $scope.filteredMeals = $scope.selectedCycle.Meals.map(meal => {\r\n var mealNameMatch = meal.MealName.toLowerCase().includes(searchTextLower);\r\n\r\n // Filter meal items that match search criteria\r\n var filteredMealItems = meal.MealItems.map(item => {\r\n var itemNameMatch = item.ItemName.toLowerCase().includes(searchTextLower);\r\n var allergenMatch = item.Allergen ? item.Allergen.toLowerCase().includes(searchTextLower) : false;\r\n var compositionMatch = item.Composition ? item.Composition.toLowerCase().includes(searchTextLower) : false;\r\n\r\n var matchFound = itemNameMatch || allergenMatch || compositionMatch;\r\n item.highlight = matchFound; // Highlight matched items\r\n\r\n return item;\r\n }).filter(item => item.highlight);\r\n\r\n // Return the meal if it or its items match the search\r\n if (mealNameMatch || filteredMealItems.length > 0) {\r\n return {\r\n ...meal,\r\n MealItems: filteredMealItems,\r\n highlight: mealNameMatch\r\n };\r\n }\r\n return null;\r\n }).filter(meal => meal !== null);\r\n\r\n // If \"All Cycles\" is selected, filter meals from all cycles in the selected service\r\n } else if ($scope.isAllCyclesSelected) {\r\n $scope.filteredMeals = $scope.selectedService.ServiceCycles\r\n .flatMap(cycle => cycle.Meals.map(meal => {\r\n var mealNameMatch = meal.MealName.toLowerCase().includes(searchTextLower);\r\n\r\n var filteredMealItems = meal.MealItems.map(item => {\r\n var itemNameMatch = item.ItemName.toLowerCase().includes(searchTextLower);\r\n var allergenMatch = item.Allergen ? item.Allergen.toLowerCase().includes(searchTextLower) : false;\r\n var compositionMatch = item.Composition ? item.Composition.toLowerCase().includes(searchTextLower) : false;\r\n\r\n var matchFound = itemNameMatch || allergenMatch || compositionMatch;\r\n item.highlight = matchFound;\r\n\r\n return item;\r\n }).filter(item => item.highlight);\r\n\r\n if (mealNameMatch || filteredMealItems.length > 0) {\r\n return {\r\n ...meal,\r\n MealItems: filteredMealItems,\r\n highlight: mealNameMatch\r\n };\r\n }\r\n return null;\r\n }))\r\n .filter(meal => meal !== null)\r\n .sort((a, b) => a.MealName.localeCompare(b.MealName)); // Sort meals alphabetically\r\n } else {\r\n // If no cycle is selected, reset the meals (optional behavior if needed)\r\n $scope.filteredMeals = [];\r\n }\r\n\r\n } else {\r\n // If the search text is empty, show all meals for the selected cycle or all cycles\r\n if ($scope.selectedCycle) {\r\n $scope.filteredMeals = $scope.selectedCycle.Meals;\r\n } else if ($scope.isAllCyclesSelected) {\r\n $scope.filteredMeals = $scope.selectedService.ServiceCycles\r\n .flatMap(cycle => cycle.Meals)\r\n .sort((a, b) => a.MealName.localeCompare(b.MealName)); // Sort meals alphabetically\r\n } else {\r\n $scope.filteredMeals = [];\r\n }\r\n }\r\n }\r\n\r\n // Toggle visibility of meal details\r\n $scope.toggleVisibility = function (meal) {\r\n meal.isInfoVisible = !meal.isInfoVisible;\r\n };\r\n \r\n function toggleSidePanel() {\r\n $scope.shownSideMenu = !$scope.shownSideMenu;\r\n }\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('PassengerMealServiceFactory', PassengerMealServiceFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PassengerMealServiceFactory\r\n * @description \r\n * Add, Update, Delete and Get Passenger meals allergen info.\r\n * @ngInject\r\n */\r\n function PassengerMealServiceFactory(IndexedDBService) {\r\n\r\n /**\r\n * Initialize MealAllergen\r\n * @memberof PassengerMealServiceFactory\r\n */\r\n function PassengerMealService() {\r\n this.Id = null;\r\n }\r\n\r\n var objType = 'PassengerMealServices';\r\n var objCallback = PassengerMealService;\r\n\r\n var service = {\r\n setPassengerMealsServicesToStorage: setPassengerMealsServicesToStorage,\r\n getPassengerMealServicesFromStorage: getPassengerMealServicesFromStorage,\r\n getPassengerMealServiceFromStorage: getPassengerMealServiceFromStorage,\r\n checkAndsetPassengerMealsServicesToStorage: checkAndsetPassengerMealsServicesToStorage\r\n }\r\n\r\n /**\r\n * Get all passenger meal services\r\n * @memberof PassengerMealServiceFactory\r\n * @param {function} callback \r\n */\r\n function getPassengerMealServicesFromStorage(callback) {\r\n IndexedDBService.getAll(objType).then(function (results) {\r\n callback(results);\r\n });\r\n };\r\n \r\n function checkAndsetPassengerMealsServicesToStorage(callback) {\r\n // Check if callback is null or undefined\r\n if (!callback || callback.length === 0) { \r\n return; // Exit the function if callback is null\r\n }\r\n\r\n IndexedDBService.getAll(objType).then(function (results) {\r\n // Handle cases where results are null or undefined\r\n if (!results || results.length === 0) {\r\n setPassengerMealsServicesToStorage(callback);\r\n }\r\n else {\r\n // Filter out any undefined or null entries in the results array\r\n var validResults = results.filter(service => service && service.CreatedDate);\r\n\r\n // Check if validResults contains any valid services\r\n if (validResults.length > 0) {\r\n var storedLatestService = validResults.reduce((latest, current) => {\r\n return new Date(latest.CreatedDate) > new Date(current.CreatedDate) ? latest : current;\r\n });\r\n\r\n var firstNewService = callback[0];\r\n // Compare the dates\r\n var storedCreatedDate = new Date(storedLatestService.CreatedDate);\r\n var newCreatedDate = new Date(firstNewService.CreatedDate);\r\n\r\n if (newCreatedDate > storedCreatedDate) {\r\n IndexedDBService.removeAll(objType).then(function () {\r\n setPassengerMealsServicesToStorage(callback);\r\n });\r\n }\r\n } else {\r\n // If all entries are invalid, remove all entries from IndexedDB\r\n IndexedDBService.removeAll(objType).then(function () {\r\n setPassengerMealsServicesToStorage(callback);\r\n });\r\n }\r\n }\r\n });\r\n }\r\n \r\n \r\n function setPassengerMealsServicesToStorage(callback) {\r\n IndexedDBService.addAll(objType, callback);\r\n };\r\n\r\n /**\r\n * Get passenger meal service By Id\r\n * @memberof PassengerMealServiceFactory\r\n * @param {function} callback \r\n */\r\n function getPassengerMealServiceFromStorage(serviceId, callback, errorCallback) {\r\n IndexedDBService.getById(objType, serviceId).then(function(result) {\r\n callback(result);\r\n }).catch(errorCallback);\r\n };\r\n \r\n return service;\r\n }\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.controller('PassengerCtrl', PassengerCtrl)\r\n\r\n\t/**\r\n\t* @memberof CabinReports\r\n\t* @ngdoc controller\r\n\t* @name PassengerCtrl\r\n\t* @description \r\n\t* Manages the passenger information view\r\n\t* @ngInject\r\n\t*/\r\n\tfunction PassengerCtrl(passenger, flightId, report, paxInfo, LuggageComplianceFactory, CampaignFactory, $scope, $uibModalInstance, $timeout, FlightFactory, CabinReportLocalEditFactory, CabinReportLocalEditCreatorFactory,\r\n\t\t\t\t\t\t UserFactory, WifiVouchersFactory, WifiAvailabilityFactory) {\r\n\r\n\t\t$scope.ReportIsFinal = false;\r\n\t\tvar flight = FlightFactory.getFlightFromStorage(flightId);\r\n\t\tvar user = UserFactory.getUser();\r\n\t\tif (isInFinalState(flight))\r\n\t\t\t$scope.ReportIsFinal = true;\r\n\t\t$scope.closeModal = closeModal;\r\n\t\t$scope.passenger = passenger;\r\n\t\t//ugrade passenger \r\n\t\t$scope.ugradePassenger = {\r\n\t\t\tshowUpgradeInput: false,\r\n\t\t\tshowUpgradeWarning: false,\r\n\t\t\tshowUpgradeError: false,\r\n\t\t\tshowSuccess: false,\r\n\t\t\tupgradedSeatNo: '',\r\n\t\t\tsuccessMessage: '',\r\n\t\t\tupgradeRemarks: ''\r\n\t\t}\r\n\r\n\t\t$scope.submitUpgrade = submitUpgrade;\r\n\t\t$scope.saveUpgrade = saveUpgrade;\r\n\t\t$scope.undo = undo;\r\n\r\n\t\t//wifi scopes:\r\n\t\tvar wifiAvailability = WifiAvailabilityFactory.getRegistrationsFromStorage();\r\n\t\tif(wifiAvailability){\r\n\t\t\t$scope.supportsWifi = wifiAvailability.registrations.includes(flight.AcTailNo);\r\n\t\t}else{\r\n\t\t\t$scope.supportsWifi = false;\r\n\t\t}\r\n\t\t$scope.retrieveWifiVouchers = retrieveWifiVouchers;\r\n\t\t$scope.showPanel = '';\r\n\t\t$scope.notRetrieved = true;\r\n\t\t$scope.createTextVoucher = createTextVoucher;\r\n\t\t$scope.createStreamVoucher = createStreamVoucher;\r\n\r\n\t\t//Seat Change \r\n\t\tif (passenger.ChangedSeat) {\r\n\t\t\t$scope.passenger.IsSeatChanged = true;\r\n\t\t} else {\r\n\t\t\t$scope.passenger.IsSeatChanged = false;\r\n\t\t}\r\n\t\t$scope.changeSeatFormData = { changedSeatNo: '', seatChangeRemarks: '', showSeatChangeInput: false };\r\n\t\t$scope.showSeatChangeWarning = false;\r\n\t\t$scope.showSeatChangeError = false;\r\n\t\t$scope.showSeatChangeSuccess = false;\r\n\t\t$scope.successSeatChangeMessage = '';\r\n\t\t$scope.submitSeatChange = submitSeatChange;\r\n\t\t$scope.undoSeatChange = undoSeatChange;\r\n\t\t$scope.saveSeatChange = saveSeatChange;\r\n\t\t$scope.closeChangeWarning = closeChangeWarning;\r\n\r\n\t\t$scope.linkedPassengersGroup = [];\r\n\t\t$scope.IsOld = IsOld;\r\n\t\t$scope.giftStatus = CampaignFactory.giftStatusList();\r\n\t\t$scope.isFeedbackUpdated = false;\r\n\t\t$scope.submitCampaignFeedback = submitCampaignFeedback;\r\n\t\t$scope.hideFooter = true;\r\n\t\t$scope.showOneStopShop = false;\r\n\t\t\r\n\t\t$scope.toggleFooter = toggleFooter;\r\n\t\t$scope.treatmentAvailability = treatmentAvailability;\r\n\r\n\t\tfunction toggleFooter(hide){\r\n\t\t\t$scope.hideFooter = hide;\r\n\t\t}\r\n\r\n\t\t// Cabin Luggage Report\r\n\t\t$scope.saEligibility = flight.LineStatus != 'na';\r\n\t\t$scope.flightCompliant = LuggageComplianceFactory.getFlightCompliantStatus(flightId);\r\n\t\t$scope.updateCabinLuggageReport = updateCabinLuggageReport;\r\n\t\tvar luggageReport = LuggageComplianceFactory.getPassengerLuggageCompliance(flightId, $scope.passenger.UCI)\r\n\t\t$scope.passenger.luggageCompliance = {\r\n\t\t\thasTwoLuggage: luggageReport != null,\r\n\t\t\tisSynced: luggageReport && luggageReport.isSynced\r\n\t\t};\r\n\r\n\t\tgetlinkedPassengers();\r\n\t\t/**\r\n\t\t * Gets called when user hits submit. Checks input then saves it\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction submitUpgrade() {\r\n\t\t\t$scope.ugradePassenger.showUpgradeWarning = false;\r\n\t\t\t$scope.ugradePassenger.showUpgradeError = false;\r\n\t\t\tif (!isSeatAvailableForUpgrate()) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tsaveUpgrade();\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Gets called when input is ready\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction saveUpgrade() {\r\n\t\t\t$scope.ugradePassenger.showUpgradeWarning = false;\r\n\t\t\t$scope.ugradePassenger.showUpgradeError = false;\r\n\t\t\tupdateReport();\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Checks if report is finalized\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction isInFinalState(flight) {\r\n\t\t\tvar isInFinalState = ((flight.LineStatus === 'na') ||\r\n\t\t\t\t(flight.LineStatus === 'stored') ||\r\n\t\t\t\t(flight.LineStatus === 'storedotheruser') ||\r\n\t\t\t\t(flight.LineStatus === 'stored+otheruser') ||\r\n\t\t\t\t(flight.LineStatus === 'synched') ||\r\n\t\t\t\t(flight.LineStatus === 'synchedotheruser'));\r\n\t\t\treturn isInFinalState;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * fix any input into 000A format\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction formatSeatInput() {\r\n\t\t\tvar missingZeroes = 4 - $scope.ugradePassenger.upgradedSeatNo.length;\r\n\t\t\tfor (var i = 0; i < missingZeroes; i++)\r\n\t\t\t\t$scope.ugradePassenger.upgradedSeatNo = '0' + $scope.ugradePassenger.upgradedSeatNo;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Puts the new seat upgrade in the report\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction updateReport() {\r\n\t\t\tvar upgradedPassenger = {\r\n\t\t\t\tPNR: $scope.passenger.PNR,\r\n\t\t\t\tUCI: $scope.passenger.UCI,\r\n\t\t\t\tOriginalSeatNo: $scope.passenger.SeatNo,\r\n\t\t\t\tUpgradedSeatNo: $scope.ugradePassenger.upgradedSeatNo,\r\n\t\t\t\tRemarks: $scope.ugradePassenger.upgradeRemarks\r\n\t\t\t}\r\n\r\n\r\n\t\t\tif (report) {\r\n\t\t\t\treport.UpgradedPassengers.push(upgradedPassenger);\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\treport = CabinReportLocalEditCreatorFactory.createNewLocalReportForFlight(flightId);\r\n\t\t\t\treport.UpgradedPassengers.push(upgradedPassenger);\r\n\t\t\t\treport.Status = 'draft';\r\n\t\t\t\treport.saveReport();\r\n\t\t\t\tFlightFactory.updateFlightFromReport(report);\r\n\t\t\t}\r\n\r\n\t\t\tCabinReportLocalEditFactory.setCabinReportToStorage(report);\r\n\t\t\t$scope.passenger.UpgradedToSeat = upgradedPassenger;\r\n\t\t\t$scope.ugradePassenger.showSuccess = true;\r\n\t\t\t$scope.ugradePassenger.successMessage = 'Upgrade submitted successfully!';\r\n\t\t\t$timeout(function () {\r\n\t\t\t\t$scope.ugradePassenger.showSuccess = false;\r\n\t\t\t}, 3500);\r\n\t\t}\r\n\r\n\r\n\t\t/**\r\n\t * Fills up the linked Passengers list. \r\n\t * @memberof PassengerCtrl\r\n\t */\r\n\t\tfunction getlinkedPassengers() {\r\n\t\t\tif (paxInfo && passenger.UCI) {\r\n\t\t\t\tfor (var i = 0; i < paxInfo.Seatmap.length; i++) {\r\n\t\t\t\t\tfor (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\r\n\t\t\t\t\t\tif (passenger.LinkedPassengers && passenger.LinkedPassengers.includes(paxInfo.Seatmap[i].Columns[j].UCI)) {\r\n\t\t\t\t\t\t\t$scope.linkedPassengersGroup.push(paxInfo.Seatmap[i].Columns[j].SeatNo);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (passenger.LinkedPassengersWithProductId && passenger.LinkedPassengersWithProductId.includes(paxInfo.Seatmap[i].Columns[j].ProductId)) {\r\n\t\t\t\t\t\t\t$scope.linkedPassengersGroup.push(paxInfo.Seatmap[i].Columns[j].SeatNo);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Removes upgrade from report\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction undo() {\r\n\t\t\tif (report) {\r\n\t\t\t\treport.UpgradedPassengers = report.UpgradedPassengers.filter(function (p) {\r\n\t\t\t\t\treturn p.OriginalSeatNo != passenger.SeatNo && p.UCI != passenger.UCI;\r\n\t\t\t\t});\r\n\r\n\t\t\t\treport.saveReport();\r\n\t\t\t\tFlightFactory.updateFlightFromReport(report);\r\n\t\t\t\tCabinReportLocalEditFactory.setCabinReportToStorage(report);\r\n\t\t\t}\r\n\t\t\t$scope.passenger.UpgradedToSeat = false;\r\n\t\t\t$scope.ugradePassenger.showSuccess = true;\r\n\t\t\t$scope.ugradePassenger.successMessage = 'Upgrade removed successfuly!';\r\n\t\t\t$timeout(function () {\r\n\t\t\t\t$scope.ugradePassenger.showSuccess = false;\r\n\t\t\t}, 3500);\r\n\t\t\t$scope.ugradePassenger.showUpgradeInput = false;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Checks if the seat is available and fires warnings or errors\r\n\t\t * @memberof PassengerCtrl\r\n\t\t * @param {string} seat The seat number \r\n\t\t * @return {boolean} isSeatAvailableForUpgrate\r\n\t\t */\r\n\t\tfunction isSeatAvailableForUpgrate() {\r\n\t\t\t$scope.ugradePassenger.upgradedSeatNo = $scope.ugradePassenger.upgradedSeatNo.toUpperCase();\r\n\t\t\tformatSeatInput();\r\n\r\n\t\t\tif (paxInfo) {\r\n\t\t\t\tfor (var i = 0; i < paxInfo.Seatmap.length; i++) {\r\n\t\t\t\t\tfor (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\r\n\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns[j].SeatNo == $scope.ugradePassenger.upgradedSeatNo) {\r\n\t\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns[j].IsEmptySeat) {\r\n\t\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t$scope.ugradePassenger.showUpgradeWarning = true;\r\n\t\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t//not found in seatmap\r\n\t\t\t$scope.showSeatChangeError = true;\r\n\t\t\t$scope.ugradePassenger.upgradedSeatNo = '';\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\r\n\t\t// Seat Change\r\n\t\t/**\r\n\t\t * Checks if the seat is available and fires warnings or errors\r\n\t\t * @memberof PassengerCtrl\r\n\t\t * @param {string} seat The seat number \r\n\t\t * @return {boolean} isSeatAvailableForChange\r\n\t\t */\r\n\t\tfunction isSeatAvailableForChange() {\r\n\r\n\t\t\t/** fix any input into 000A format */\r\n\t\t\tvar missingZeroes = 4 - $scope.changeSeatFormData.changedSeatNo.length;\r\n\t\t\tfor (var i = 0; i < missingZeroes; i++)\r\n\t\t\t\t$scope.changeSeatFormData.changedSeatNo = '0' + $scope.changeSeatFormData.changedSeatNo;\r\n\t\t\t$scope.changeSeatFormData.changedSeatNo = $scope.changeSeatFormData.changedSeatNo.toUpperCase();\r\n\r\n\t\t\tif (paxInfo) {\r\n\t\t\t\tfor (var i = 0; i < paxInfo.Seatmap.length; i++) {\r\n\t\t\t\t\tfor (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\r\n\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns[j].SeatNo == $scope.changeSeatFormData.changedSeatNo) {\r\n\t\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns[j].IsEmptySeat && !IsAlreadyGivenSeat($scope.changeSeatFormData.changedSeatNo)) {\r\n\t\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t$scope.showSeatChangeWarning = true;\r\n\t\t\t\t\t\t\t\treturn false;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t//not found in seatmap\r\n\t\t\t$scope.showSeatChangeError = true;\r\n\t\t\t$timeout(function () {\r\n\t\t\t\t$scope.showSeatChangeError = false;\r\n\t\t\t\t$scope.changeSeatFormData.changedSeatNo = '';\r\n\t\t\t}, 3500);\r\n\t\t\treturn false;\r\n\r\n\t\t}\r\n\r\n\t\tfunction IsAlreadyGivenSeat(newSeatNo) {\r\n\t\t\treturn report.ChangedSeats.some(function (item) {\r\n\t\t\t\treturn item.NewSeatNo == newSeatNo;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Gets called when user hits submit. Checks input then saves it\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction submitSeatChange() {\r\n\t\t\t$scope.showSeatChangeWarning = false;\r\n\t\t\t$scope.showSeatChangeError = false;\r\n\t\t\tif (!isSeatAvailableForChange()) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tsaveSeatChange();\r\n\t\t}\r\n\r\n\t\tfunction closeChangeWarning() {\r\n\t\t\t$scope.changeSeatFormData.showSeatChangeInput = !$scope.changeSeatFormData.showSeatChangeInput;\r\n\t\t\t$scope.showSeatChangeWarning = false;\r\n\t\t\t$scope.showSeatChangeError = false;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Gets called when input is ready\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction saveSeatChange() {\r\n\t\t\t$scope.showSeatChangeWarning = false;\r\n\t\t\t$scope.showSeatChangeError = false;\r\n\t\t\tupdateReportForSeatChange();\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Puts the new seat change in the report\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction updateReportForSeatChange() {\r\n\r\n\t\t\tvar changedSeat = {\r\n\t\t\t\tName: $scope.passenger.Fullname,\r\n\t\t\t\tPNR: $scope.passenger.PNR,\r\n\t\t\t\tUCI: $scope.passenger.UCI,\r\n\t\t\t\tOriginalSeatNo: $scope.passenger.SeatNo,\r\n\t\t\t\tNewSeatNo: $scope.changeSeatFormData.changedSeatNo,\r\n\t\t\t\tRemarks: $scope.changeSeatFormData.seatChangeRemarks\r\n\t\t\t}\r\n\r\n\t\t\tif (report) {\r\n\t\t\t\treport.ChangedSeats.push(changedSeat);\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\treport = CabinReportLocalEditCreatorFactory.createNewLocalReportForFlight(flightId);\r\n\t\t\t\treport.ChangedSeats.push(changedSeat);\r\n\t\t\t\treport.Status = 'draft';\r\n\t\t\t\treport.saveReport();\r\n\t\t\t\tFlightFactory.updateFlightFromReport(report);\r\n\t\t\t}\r\n\r\n\t\t\tCabinReportLocalEditFactory.setCabinReportToStorage(report);\r\n\t\t\t$scope.passenger.ChangedSeat = changedSeat;\r\n\t\t\t$scope.passenger.IsSeatChanged = true;\r\n\t\t\t$scope.showSeatChangeSuccess = true;\r\n\t\t\t$scope.successSeatChangeMessage = 'Seat change submitted successfully!';\r\n\t\t\t$timeout(function () {\r\n\t\t\t\t$scope.showSeatChangeSuccess = false;\r\n\t\t\t}, 3500);\r\n\r\n\t\t}\r\n\r\n\r\n\t\t/**\r\n\t\t * Removes seat change from report\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction undoSeatChange() {\r\n\t\t\tif (report) {\r\n\t\t\t\treport.ChangedSeats = report.ChangedSeats.filter(function (p) {\r\n\t\t\t\t\treturn p.OriginalSeatNo != passenger.SeatNo && p.UCI != passenger.UCI;\r\n\t\t\t\t});\r\n\r\n\t\t\t\treport.saveReport();\r\n\t\t\t\tFlightFactory.updateFlightFromReport(report);\r\n\t\t\t\tCabinReportLocalEditFactory.setCabinReportToStorage(report);\r\n\t\t\t}\r\n\t\t\t$scope.passenger.ChangedSeat = null; // ?\r\n\t\t\t$scope.passenger.IsSeatChanged = false;\r\n\t\t\t$scope.showSeatChangeSuccess = true;\r\n\t\t\t$scope.successSeatChangeMessage = 'Seat change removed successfuly!';\r\n\t\t\t$scope.changeSeatFormData.showSeatChangeInput = false;\r\n\t\t\t$timeout(function () {\r\n\t\t\t\t$scope.showSeatChangeSuccess = false;\r\n\t\t\t}, 3500);\r\n\t\t}\r\n\r\n\r\n\t\t/**\r\n\t\t * Checks if the data are new\r\n\t\t * @memberof PassengerCtrl\r\n\t\t * @param {string} time timestamp\r\n\t\t * @return {boolean} IsOld\r\n\t\t */\r\n\t\tfunction IsOld(time) {\r\n\t\t\tIsOld = false;\r\n\t\t\tif (time) {\r\n\t\t\t\tvar now = new Date();\r\n\t\t\t\tvar timeDate = new Date(time);\r\n\t\t\t\tvar diff = now.getTime() - timeDate.getTime();\r\n\t\t\t\tif (diff > 3600000) {\r\n\t\t\t\t\tIsOld = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn IsOld;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Add or remove passenger from the Cabin Luggage Compliance Report\r\n\t\t * */\r\n\t\tfunction updateCabinLuggageReport() {\r\n\t\t\tvar cabinLuggageReport = {\r\n\t\t\t\tisChecked: $scope.passenger.luggageCompliance.hasTwoLuggage,\r\n\t\t\t\tPNR: $scope.passenger.PNR,\r\n\t\t\t\tUCI: $scope.passenger.UCI,\r\n\t\t\t\tFlightId: $scope.flight.FlightId,\r\n\t\t\t\tFareFamily: $scope.passenger.FareFamily,\r\n\t\t\t\tIsFlightCompliant: false,\r\n\t\t\t\tCreated: moment()\r\n\t\t\t};\r\n\r\n\t\t\tLuggageComplianceFactory.setLuggageComplianceToStorage(cabinLuggageReport);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Close the modal\r\n\t\t * @memberof PassengerCtrl\r\n\t\t */\r\n\t\tfunction closeModal() {\r\n\t\t\t$uibModalInstance.dismiss('');\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Close the modal\r\n\t\t* @memberof PassengerCtrl\r\n\t\t*/\r\n\t\tfunction submitCampaignFeedback() {\r\n\t\t\t$scope.passenger.Campaign.assignment.Status = +$scope.passenger.Campaign.assignment.StatusStr;\r\n\t\t\tCampaignFactory.updateCampaignPassenger(+flightId, $scope.passenger.Campaign.assignment);\r\n\t\t\t$scope.isFeedbackUpdated = true;\r\n\t\t\t$timeout(function () {\r\n\t\t\t\t$scope.isFeedbackUpdated = false;\r\n\t\t\t}, 3500);\r\n\t\t}\r\n\t\t\r\n\t\t/**\r\n\t\t * Manages OneStopShop tab visibility\r\n\t\t * Gets called if there are OneStopShop treatments available for this passenger\r\n\t\t */\r\n\t\t function treatmentAvailability(counter){\r\n\t\t\tif(user.position == \"SA\"){\r\n\t\t\t\t$scope.ossCounter = counter;\r\n\t\t\t\t$scope.showOneStopShop = true;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Retrieve wifi vouchers\r\n\t\t* @memberof PassengerCtrl\r\n\t\t*/\r\n\t\tfunction retrieveWifiVouchers(pnr) {\r\n\t\t\t$scope.showPanel = \"loading\";\r\n\t\t\r\n\t\t\tvar RequestWifiVouchers = {\r\n\t\t\t\tPNR: pnr,\r\n\t\t\t\tFlightId: $scope.flight.FlightId,\r\n\t\t\t\tFlightDate: passenger.STDLocal\r\n\t\t\t};\r\n\r\n\t\t\tWifiVouchersFactory.retrieveWifiVouchers(RequestWifiVouchers)\r\n\t\t\t\t.then(res => retrieveHandleSubmitResponse(res));\t\t\t\r\n\t\t}\r\n\r\n\t\tfunction retrieveHandleSubmitResponse(res){\r\n\t\t\t$scope.newVoucherCode = false;\r\n\t\t\thandleSubmitResponse(res);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Create wifi voucher - \"Text and surf\"\r\n\t\t* @memberof PassengerCtrl\r\n\t\t*/\r\n\t\tfunction createTextVoucher() {\r\n\t\t\t$scope.showPanel = \"loading\";\r\n\t\t\tvar RequestCreateVoucher = {\r\n\t\t\t\tPNR: passenger.PNR,\r\n\t\t\t\tFlightId: $scope.flight.FlightId,\r\n\t\t\t\tFlightNumber: $scope.flight.FlightNo,\r\n\t\t\t\tFullName: passenger.Fullname,\r\n\t\t\t\tPlanId: \"2902\",\r\n\t\t\t\tFlightDate: passenger.STDLocal\r\n\t\t\t};\r\n\t\t\tWifiVouchersFactory.createWifiVoucher(RequestCreateVoucher)\r\n\t\t\t.then(res => createHandleSubmitResponse(res));\t\t\t\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Create wifi voucher - \"Stream\"\r\n\t\t* @memberof PassengerCtrl\r\n\t\t*/\r\n\t\tfunction createStreamVoucher(params) {\r\n\t\t\t$scope.showPanel = \"loading\";\r\n\t\t\tvar RequestCreateVoucher = {\r\n\t\t\t\tPNR: passenger.PNR,\r\n\t\t\t\tFlightId: $scope.flight.FlightId,\r\n\t\t\t\tFlightNumber: $scope.flight.FlightNo,\r\n\t\t\t\tFullName: passenger.Fullname,\r\n\t\t\t\tPlanId: \"2904\",\r\n\t\t\t\tFlightDate: passenger.STDLocal\r\n\t\t\t};\r\n\t\t\tWifiVouchersFactory.createWifiVoucher(RequestCreateVoucher)\r\n\t\t\t .then(res => createHandleSubmitResponse(res));\t\t\t\t\r\n\t\t}\r\n\r\n\t\tfunction createHandleSubmitResponse(res){\r\n\t\t\t$scope.newVoucherCode = true;\r\n\t\t\thandleSubmitResponse(res);\r\n\t\t}\r\n\r\n\t\tfunction handleSubmitResponse(res) {\r\n\t\t\tif (res.success) {\r\n\t\t\t\tif($scope.newVoucherCode == false){\r\n\t\t\t\t\t$scope.textAndSurfCodes = [];\r\n\t\t\t\t\t$scope.streamCodes = [];\r\n\t\t\t\t\t$scope.newVouchers = [];\r\n\t\t\t\t}else{\r\n\t\t\t\t\t$scope.newVouchers = res.data;\r\n\t\t\t\t}\r\n\t\t\t\t$scope.notRetrieved = false;\r\n\t\t\t\tmanageResponseMessage(\"success\", res.message);\r\n\t\t\t\t$scope.wifiVouchersCodes = res.data;\r\n\r\n\t\t\t\t$scope.wifiVouchersCodes.forEach(function (code) {\r\n if(code.Type == 'Text & Surf') {\r\n $scope.textAndSurfCodes.push(code.VoucherCode);\r\n }\r\n });\r\n\r\n\t\t\t\t$scope.wifiVouchersCodes.forEach(function (code) {\r\n if(code.Type == 'Stream') {\r\n $scope.streamCodes.push(code.VoucherCode);\r\n }\r\n }); \r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t$scope.newVoucherCode = false;\r\n\t\t\t\tmanageResponseMessage(\"failure\", res.message);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\t/**\r\n\t\t* Manage message alerts\r\n\t\t* @param {string} panelToShow \r\n\t\t* @param {string} message \r\n\t\t*/\r\n\t\tfunction manageResponseMessage(panelToShow, message) {\r\n\t\t\t$scope.submitMessage = message;\r\n\t\t\t$scope.showPanel = panelToShow;\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.controller('PaxCtrl', PaxCtrl);\r\n\r\n\t/**\r\n\t* @memberof CabinReports\r\n\t* @ngdoc controller\r\n\t* @name PaxCtrl\r\n\t* @description \r\n\t* Manages the passenger seatmap and information view\r\n\t* @ngInject\r\n\t*/\r\n\tfunction PaxCtrl($scope, FlightFactory, PaxInfoFactory, CampaignFactory, CabinReportLocalEditFactory, LuggageComplianceFactory, UserFactory, $route, $routeParams, $uibModal, $location) {\r\n\t\tvar flightId = $routeParams.flightId;\r\n\t\tvar flight = FlightFactory.getFlightFromStorage(flightId);\r\n\t\tvar report = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId);\r\n\r\n\t\t$scope.state = 'pax';\r\n\t\t$scope.flight = flight;\r\n\t\t$scope.showMobileMenuFilters = false;\r\n\t\t$scope.filterPax = filterPax;\r\n\t\t$scope.viewMode = viewMode;\r\n\t\t$scope.filterRow = filterRow;\r\n\t\t$scope.filterCol = filterCol;\r\n\t\t$scope.howClose = '';\r\n\t\t$scope.IsOld = IsOld;\r\n\t\t$scope.openPassenger = openPassenger;\r\n\t\t$scope.resetFilters = resetFilters;\r\n\t\t$scope.isConnectedFlightClose = isConnectedFlightClose;\r\n\t\t$scope.TimeDifference = TimeDifference;\r\n\t\t$scope.applyLuggageCompliance = applyLuggageCompliance;\r\n\t\t$scope.IsProvisional = true;\r\n\t\t$scope.specialMeals = 0;\r\n\t\t$scope.multiSelectCount = 0;\r\n\t\t$scope.luggageComplianceConfirmation = luggageComplianceConfirmation;\r\n\t\t$scope.close = close;\r\n\t\t$scope.toggleFlightInfoView = toggleFlightInfoView;\r\n\t\t$scope.mode = \"seatMap\";\r\n\t\t$scope.radioModel = \"Seatmap\";\r\n\r\n\t\t$scope.flightCompliant = LuggageComplianceFactory.getFlightCompliantStatus(flightId);\r\n\r\n\t\t$scope.searchText = { passengerName: '' };\r\n\r\n\t\tvar user = UserFactory.getUser();\r\n\t\t$scope.isUserSA = user.position == 'SA' ? true : false;\r\n\r\n\t\tif (flight == null) {\r\n\t\t\tflight = FlightFactory.getLocalFlightFromStorage(flightId)\r\n\t\t}\r\n\t\r\n\t\t$scope.saEligibility = flight.LineStatus && flight.LineStatus != 'na';\r\n\r\n\t\tPaxInfoFactory.setMaskPaxInfoInRoute(flight);\r\n\r\n\t\tvar paxInfo = null;\r\n\t\tPaxInfoFactory.getPaxInfoFromStorage(flightId, function (result) {\r\n\t\t\tpaxInfo = result;\r\n\t\t\t$scope.paxInfo = paxInfo;\r\n\r\n\t\t\tif (paxInfo && report) {\r\n\t\t\t\t//Set upgraded seats and changed seats from report to paxinfo\r\n\t\t\t\tsetUpgradedSeatsFromReport(report.UpgradedPassengers);\r\n\t\t\t\tif (report.ChangedSeats) {\r\n\t\t\t\t\tsetChangedSeatsFromReport(report.ChangedSeats);\r\n\t\t\t\t\t//Get ChangedSeats Counter\r\n\t\t\t\t\t$scope.paxInfo.changedSeatsNo = report.ChangedSeats.length;\r\n\t\t\t\t} else {\r\n\t\t\t\t\t$scope.paxInfo.changedSeatsNo = 0;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (flight != null) {\r\n\t\t\t\tif (paxInfo) {\r\n\t\t\t\t\tvar connectingPax = 0;\r\n\t\t\t\t\tfor (var i = 0; i < paxInfo.ConnectingFlights.length; i++) {\r\n\t\t\t\t\t\tconnectingPax = connectingPax + paxInfo.ConnectingFlights[i].PassengerSummaryC.Passengers\r\n\t\t\t\t\t\t\t+ paxInfo.ConnectingFlights[i].PassengerSummaryY.Passengers;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$scope.connectingPax = connectingPax;\r\n\r\n\t\t\t\t\tfor (var i = 0; i < paxInfo.Seatmap.length; i++) {\r\n\t\t\t\t\t\tfor (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\r\n\r\n\t\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns.SpecialMeal) {\r\n\t\t\t\t\t\t\t\t$scope.specialMeals++\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns.SpecialMealB) {\r\n\t\t\t\t\t\t\t\t$scope.specialMeals++\r\n\t\t\t\t\t\t\t}\r\n\r\n\r\n\t\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns[j].ConnectingFlightId && paxInfo.Seatmap[i].Columns[j].ConnectingFlightId != 0) {\r\n\r\n\t\t\t\t\t\t\t\tfor (var h = 0; h < paxInfo.ConnectingFlights.length; h++) {\r\n\t\t\t\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns[j].ConnectingFlightId == paxInfo.ConnectingFlights[h].FlightId) {\r\n\t\t\t\t\t\t\t\t\t\tpaxInfo.Seatmap[i].Columns[j].Connection = paxInfo.ConnectingFlights[h];\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tvar listSentTimestamp = new Date(paxInfo.LastRun).getTime();\r\n\t\t\t\t\tvar DepartureTimestamp = new Date(flight.ScheduledDeparture).getTime();\r\n\t\t\t\t\t//20 minutes before takeoff\r\n\t\t\t\t\tif (DepartureTimestamp - listSentTimestamp <= 1200000) {\r\n\t\t\t\t\t\t$scope.IsProvisional = false;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar flightArrivalTime = new Date(flight.ScheduledArrival).getTime();\r\n\t\t\t\t$scope.flightETA = flight.ETA ? new Date(flight.ETA).getTime() : flightArrivalTime;\r\n\r\n\t\t\t\tattachCampaign($scope.paxInfo);\r\n\t\t\t\tattachLuggageCompliance();\r\n\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\tinitializeViewMode();\r\n\t\t\t} else {\r\n\t\t\t\t$location.path(\"/\");\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t/**\r\n\t\t * Set upgraded seats from report to paxinfo\r\n\t\t * @memberof PaxCtrl\r\n\t\t */\r\n\t\tfunction setUpgradedSeatsFromReport(upgradedPassengers) {\r\n\t\t\tfor (var k = 0; k < upgradedPassengers.length; k++) {\r\n\t\t\t\tfor (var i = 0; i < $scope.paxInfo.Seatmap.length; i++) {\r\n\t\t\t\t\tfor (var j = 0; j < $scope.paxInfo.Seatmap[i].Columns.length; j++) {\r\n\t\t\t\t\t\tif ($scope.paxInfo.Seatmap[i].Columns[j].UCI == upgradedPassengers[k].UCI && $scope.paxInfo.Seatmap[i].Columns[j].PNR == upgradedPassengers[k].PNR) {\r\n\t\t\t\t\t\t\t$scope.paxInfo.Seatmap[i].Columns[j].UpgradedToSeat = upgradedPassengers[k];\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t/**\r\n\t\t * Set changed seats from report to paxinfo\r\n\t\t * @memberof PaxCtrl\r\n\t\t */\r\n\t\tfunction setChangedSeatsFromReport(changedSeats) {\r\n\t\t\tfor (var k = 0; k < changedSeats.length; k++) {\r\n\t\t\t\tfor (var i = 0; i < $scope.paxInfo.Seatmap.length; i++) {\r\n\t\t\t\t\tfor (var j = 0; j < $scope.paxInfo.Seatmap[i].Columns.length; j++) {\r\n\t\t\t\t\t\tif ($scope.paxInfo.Seatmap[i].Columns[j].UCI == changedSeats[k].UCI && $scope.paxInfo.Seatmap[i].Columns[j].PNR == changedSeats[k].PNR) {\r\n\t\t\t\t\t\t\t$scope.paxInfo.Seatmap[i].Columns[j].ChangedSeat = changedSeats[k];\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Toggle view from seatmap to paxlist\r\n\t\t * @memberof PaxCtrl\r\n\t\t */\r\n\t\tfunction toggleFlightInfoView(mode) {\r\n\t\t\t$scope.mode = mode;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Initialize Passenger Filters\r\n\t\t * @memberof PaxCtrl\r\n\t\t */\r\n\t\tfunction initializeFilters() {\r\n\t\t\t$scope.filterPaxC = false;\r\n\t\t\t$scope.filterPaxY = false;\r\n\t\t\t$scope.filterAdults = false;\r\n\t\t\t$scope.filterChildren = false;\r\n\t\t\t$scope.filterInfants = false;\r\n\t\t\t$scope.filterUMs = false;\r\n\t\t\t$scope.filterFqtv = false;\r\n\t\t\t$scope.filterConnections = false;\r\n\t\t\t$scope.filterSpecialMeals = false;\r\n\t\t\t$scope.filterFqtvSilver = false;\r\n\t\t\t$scope.filterFqtvGold = false;\r\n\t\t\t$scope.filterWheelchair = false;\r\n\t\t\t$scope.filterAssistance = false;\r\n\t\t\t$scope.filterDeportees = false;\r\n\t\t\t$scope.filterVIP = false;\r\n\t\t\t$scope.filterDHC = false;\r\n\t\t\t$scope.filterChargeableSeats = false;\r\n\t\t\t$scope.filterEligibleForUpgrade = false;\r\n\t\t\t$scope.filterSeatChanges = false;\r\n\t\t\t$scope.filterIrregularities = false;\r\n\t\t\t$scope.filterCampaigns = false;\r\n\t\t\t$scope.multiSelect = false;\r\n\t\t\t// $scope.searchText = { passengerName: ''};\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Filter Passenger by given filter\r\n\t\t * @memberof PaxCtrl\r\n\t\t * @param {string} criteria The selected filter criteria\r\n\t\t */\r\n\t\tfunction filterPax(criteria) {\r\n\t\t\tif (criteria == \"PaxC\") {\r\n\t\t\t\tvar val = !$scope.filterPaxC;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterPaxC = val;\r\n\t\t\t} else if (criteria == \"PaxY\") {\r\n\t\t\t\tvar val = !$scope.filterPaxY;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterPaxY = val;\r\n\t\t\t} else if (criteria == \"Adults\") {\r\n\t\t\t\tvar val = !$scope.filterAdults;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterAdults = val;\r\n\t\t\t} else if (criteria == \"Children\") {\r\n\t\t\t\tvar val = !$scope.filterChildren;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterChildren = val;\r\n\t\t\t} else if (criteria == \"Infants\") {\r\n\t\t\t\tvar val = !$scope.filterInfants;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterInfants = val;\r\n\t\t\t} else if (criteria == \"Fqtv-silver\") {\r\n\t\t\t\tvar val = !$scope.filterFqtvSilver;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterFqtvSilver = val;\r\n\t\t\t} else if (criteria == \"Fqtv-gold\") {\r\n\t\t\t\tvar val = !$scope.filterFqtvGold;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterFqtvGold = val;\r\n\t\t\t} else if (criteria == \"Connections\") {\r\n\t\t\t\tvar val = !$scope.filterConnections;\r\n\t\t\t\t$scope.showConnections = true;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterConnections = val;\r\n\t\t\t} else if (criteria == \"UMs\") {\r\n\t\t\t\tvar val = !$scope.filterUMs;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterUMs = val;\r\n\t\t\t} else if (criteria == \"SpecialMeals\") {\r\n\t\t\t\tvar val = !$scope.filterSpecialMeals;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.showMeals = true;\r\n\t\t\t\t$scope.filterSpecialMeals = val;\r\n\t\t\t} else if (criteria == \"Wheelchair\") {\r\n\t\t\t\tvar val = !$scope.filterWheelchair;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterWheelchair = val;\r\n\t\t\t} else if (criteria == \"Assistance\") {\r\n\t\t\t\tvar val = !$scope.filterAssistance;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterAssistance = val;\r\n\t\t\t} else if (criteria == \"Deportees\") {\r\n\t\t\t\tvar val = !$scope.filterDeportees;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterDeportees = val;\r\n\t\t\t} else if (criteria == \"VIP\") {\r\n\t\t\t\tvar val = !$scope.filterVIP;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterVIP = val;\r\n\t\t\t} else if (criteria == \"DHC\") {\r\n\t\t\t\tvar val = !$scope.filterDHC;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterDHC = val;\r\n\t\t\t} else if (criteria == \"ChargeableSeats\") {\r\n\t\t\t\tvar val = !$scope.filterChargeableSeats;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterChargeableSeats = val;\r\n\t\t\t} else if (criteria == \"UPGD\") {\r\n\t\t\t\tvar val = !$scope.filterEligibleForUpgrade;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterEligibleForUpgrade = val;\r\n\t\t\t} else if (criteria == \"SeatChange\") {\r\n\t\t\t\tvar val = !$scope.filterSeatChanges;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterSeatChanges = val;\r\n\t\t\t} else if (criteria == \"Irregularities\") {\r\n\t\t\t\tvar val = !$scope.filterIrregularities;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterIrregularities = val;\r\n\t\t\t} else if (criteria == \"Campaigns\") {\r\n\t\t\t\tvar val = !$scope.filterCampaigns;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t\t$scope.filterCampaigns = val;\r\n\t\t\t}\r\n\t\t\telse if (criteria == \"MultiSelect\") {\r\n\t\t\t\tvar val = !$scope.multiSelect;\r\n\t\t\t\t//initializeFilters();\r\n\t\t\t\tinitialiazeMultiSelectCounter();\r\n\t\t\t\t$scope.multiSelect = val;\r\n\t\t\t}\r\n\t\t\telse if (criteria == \"searchText\") {\r\n\t\t\t\tvar val = $scope.searchText.passengerName;\r\n\t\t\t\tinitializeFilters();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction initialiazeMultiSelectCounter() {\r\n\t\t\t$scope.paxInfo.Seatmap.forEach(function (row) {\r\n\t\t\t\trow.Columns.forEach(function (column) {\r\n\t\t\t\t\tcolumn.isMultiSelected = false;\r\n\t\t\t\t});\r\n\t\t\t});\r\n\r\n\t\t\t$scope.multiSelectCount = 0;\r\n\t\t}\r\n\r\n\t\tfunction luggageComplianceConfirmation() {\r\n\t\t\tif ($scope.multiSelectCount > 0) {\r\n\t\t\t\t$scope.modalInstance = $uibModal.open({\r\n\t\t\t\t\ttemplateUrl: 'dlgLuggageComplianceConfirmation.html',\r\n\t\t\t\t\tscope: $scope\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\tfunction close() {\r\n\t\t\t$scope.modalInstance.close();\r\n\t\t}\r\n\r\n\t\tfunction applyLuggageCompliance() {\r\n\t\t\tvar columns = [];\r\n\t\t\t$scope.paxInfo.Seatmap.forEach(function (row) {\r\n\t\t\t\trow.Columns.forEach(function (column) {\r\n\t\t\t\t\tcolumns.push(column);\r\n\t\t\t\t});\r\n\t\t\t});\r\n\r\n\t\t\tvar selectedPassengers = columns.filter(c => c.isMultiSelected);\r\n\r\n\t\t\tselectedPassengers.forEach(function (passenger, index) {\r\n\t\t\t\tvar cabinLuggageReport = {\r\n\t\t\t\t\tPNR: passenger.PNR,\r\n\t\t\t\t\tUCI: passenger.UCI,\r\n\t\t\t\t\tFlightId: flightId,\r\n\t\t\t\t\tFareFamily: passenger.FareFamily,\r\n\t\t\t\t\tIsFlightCompliant: false,\r\n\t\t\t\t\tCreated: moment()\r\n\t\t\t\t};\r\n\t\t\t\tpassenger.opcc = true; //attachLuggageCompliance\r\n\t\t\t\tLuggageComplianceFactory.saveLuggageComplianceToStorage(cabinLuggageReport, index);\r\n\t\t\t});\r\n\r\n\t\t\t$scope.modalInstance.close();\r\n\t\t\tfilterPax('MultiSelect');\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Initialize View Mode\r\n\t\t * @memberof PaxCtrl\r\n\t\t */\r\n\t\tfunction initializeViewMode() {\r\n\t\t\t$scope.showPaxName = true;\r\n\t\t\t$scope.showDetails = true;\r\n\t\t\t$scope.showConnections = false;\r\n\t\t\t$scope.showMeals = false;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Set the desired view style\r\n\t\t * @memberof PaxCtrl\r\n\t\t * @param {string} mode The view mode\r\n\t\t */\r\n\t\tfunction viewMode(mode) {\r\n\t\t\tif (mode == \"PaxName\") {\r\n\t\t\t\t$scope.showPaxName = !$scope.showPaxName;\r\n\t\t\t} else if (mode == \"Details\") {\r\n\t\t\t\t$scope.showDetails = !$scope.showDetails;\r\n\t\t\t} else if (mode == \"Connections\") {\r\n\t\t\t\t$scope.showConnections = !$scope.showConnections;\r\n\t\t\t} else if (mode == \"Meals\") {\r\n\t\t\t\t$scope.showMeals = !$scope.showMeals;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Show only the Rows that have a passenger that is valid with the current filters\r\n\t\t * @memberof PaxCtrl\r\n\t\t * @param {object} row The passenger row\r\n\t\t */\r\n\t\tfunction filterRow(row) {\r\n\t\t\tvar isValid = false;\r\n\t\t\tif ($scope.filterPaxC || $scope.filterPaxY || $scope.filterAdults || $scope.filterChildren\r\n\t\t\t\t|| $scope.filterInfants || $scope.filterUMs || $scope.filterFqtv || $scope.filterConnections\r\n\t\t\t\t|| $scope.filterSpecialMeals || $scope.filterFqtvSilver || $scope.filterFqtvGold || $scope.filterWheelchair\r\n\t\t\t\t|| $scope.filterWheelchair || $scope.filterAssistance || $scope.filterDeportees || $scope.filterDHC || $scope.filterVIP\r\n\t\t\t\t|| $scope.filterChargeableSeats || $scope.filterEligibleForUpgrade || $scope.filterSeatChanges || $scope.filterIrregularities\r\n\t\t\t\t|| $scope.filterCampaigns || $scope.multiSelect || $scope.searchText.passengerName.length > 1) {\r\n\t\t\t\tfor (var i = 0; i < row.Columns.length; i++) {\r\n\t\t\t\t\tif (filterCol(row.Columns[i])) {\r\n\t\t\t\t\t\tisValid = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tisValid = true;\r\n\t\t\t}\r\n\t\t\treturn isValid;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Disable the passenger seats that is not valid with the current filters\r\n\t\t * @memberof PaxCtrl\r\n\t\t * @param {object} col The passenger seat\r\n\t\t */\r\n\t\tfunction filterCol(col) {\r\n\t\t\tvar IsValid = true;\r\n\r\n\t\t\tif ($scope.filterPaxC && col.Cabin != \"C\") {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterPaxY && col.Cabin != \"Y\") {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterAdults && col.Type != 'A') {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterChildren && col.Type != 'C') {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterInfants && (col.Type != 'I' && !(col.Type == 'A' && col.InfantName))) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterFqtv && col.Fqtv == null) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterConnections && col.Connection == null) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterUMs && !(col.SSR != null && col.SSR.IsUMNR)) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterSpecialMeals && col.SpecialMeal == null && col.SpecialMealB == null) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterFqtvSilver && !(col.Fqtv != null && (col.Fqtv.TierLevel == 'BLUT' || col.Fqtv.TierLevel == 'SLVT'))) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterFqtvGold && !(col.Fqtv != null && col.Fqtv.TierLevel == 'GLDT')) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterWheelchair && !(col.SSR != null && col.SSR.IsGroupPRM)) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterAssistance && !(col.SSR != null && (col.SSR.IsDEAF || col.SSR.IsBLND || col.SSR.IsDPNA))) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterDeportees && !(col.SSR != null && (col.SSR.IsINAD || col.SSR.IsGroupDEP))) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterVIP && !col.IsVIP) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterDHC && !col.IsDHC) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterChargeableSeats && !(col.IsCHU || col.IsCHX)) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterEligibleForUpgrade && !col.IsEligibleForUpgrade) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterSeatChanges && !col.ChangedSeat) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterIrregularities && !col.UndeliveredChargeableSeat) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t} else if ($scope.filterCampaigns && !col.Campaign) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t}\r\n\t\t\telse if ($scope.multiSelect && (col.IsEmptySeat || col.SeatMode != 'Seat')) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t}\r\n\t\t\telse if ($scope.searchText.passengerName.length > 1 && (col.Fullname == null || !col.Fullname.toLowerCase().includes($scope.searchText.passengerName.toLowerCase()))) {\r\n\t\t\t\tIsValid = false;\r\n\t\t\t}\r\n\r\n\t\t\treturn IsValid;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Initialize Passenger Filters and the desired view style\r\n\t\t * @memberof PaxCtrl\r\n\t\t */\r\n\t\tfunction resetFilters() {\r\n\t\t\tinitializeFilters();\r\n\t\t\tinitializeViewMode();\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Open Passenger Modal View\r\n\t\t * @memberof PaxCtrl\r\n\t\t * @param {object} inputObject The passenger informations\r\n\t\t */\r\n\t\tfunction openPassenger(inputObject) {\r\n\t\t\tif ($scope.multiSelect && !inputObject.IsEmptySeat && (inputObject.SeatMode == 'Seat' || inputObject.SeatMode == 'Jumpseat')) {\r\n\t\t\t\tinputObject.isMultiSelected = !inputObject.isMultiSelected;\r\n\r\n\t\t\t\tvar columns = [];\r\n\t\t\t\t$scope.paxInfo.Seatmap.forEach(function (row) {\r\n\t\t\t\t\trow.Columns.forEach(function (column) {\r\n\t\t\t\t\t\tcolumns.push(column);\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\r\n\t\t\t\t$scope.multiSelectCount = columns.filter(c => c.isMultiSelected).length;\r\n\r\n\t\t\t}\r\n\t\t\telse if (inputObject.IsEmptySeat == 0 && (inputObject.SeatMode == 'Seat' || inputObject.SeatMode == 'Jumpseat')) {\r\n\t\t\t\tvar modalInstance = $uibModal.open({\r\n\t\t\t\t\ttemplateUrl: 'views/Dialogs/dlgPassenger.html',\r\n\t\t\t\t\tcontroller: 'PassengerCtrl',\r\n\t\t\t\t\tsize: 'lg',\r\n\t\t\t\t\tbackdrop: 'static',\r\n\t\t\t\t\tkeyboard: false,\r\n\t\t\t\t\tscope: $scope,\r\n\t\t\t\t\tresolve: {\r\n\t\t\t\t\t\tpassenger: function () {\r\n\t\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\tflightId: function () {\r\n\t\t\t\t\t\t\treturn flightId;\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\tpaxInfo: function () {\r\n\t\t\t\t\t\t\treturn paxInfo;\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\treport: function () {\r\n\t\t\t\t\t\t\treturn report;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t\tmodalInstance.result.then(function () {\r\n\t\t\t\t\t//passenger upgraded, reload pax\r\n\t\t\t\t\t$route.reload();\r\n\t\t\t\t}, function () {\r\n\t\t\t\t\t//$route.reload();\r\n\t\t\t\t\tattachCampaign();\r\n\t\t\t\t\tupdateCampaignsCounters();\r\n\t\t\t\t\tattachLuggageCompliance();\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\r\n\t\t/**\r\n\t\t * Checks if the data are new\r\n\t\t * @memberof PaxCtrl\r\n\t\t * @param {string} time timestamp\r\n\t\t * @return {boolean} IsOld\r\n\t\t */\r\n\t\tfunction IsOld(time) {\r\n\t\t\tIsOld = false;\r\n\t\t\tif (time) {\r\n\t\t\t\tvar now = new Date();\r\n\t\t\t\tvar timeDate = new Date(time);\r\n\t\t\t\tvar diff = now.getTime() - timeDate.getTime();\r\n\t\t\t\tif (diff > 3600000) {\r\n\t\t\t\t\tIsOld = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn IsOld;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Calculates if a connecting flight is departs sort time after fligths arrival \r\n\t\t * @memberof PaxCtrl\r\n\t\t * @param {string} connection Connection STD\r\n\t\t * @return {string} cssClass\r\n\t\t */\r\n\t\tfunction isConnectedFlightClose(connection) {\r\n\t\t\tif (!connection) {\r\n\t\t\t\treturn '';\r\n\t\t\t}\r\n\r\n\t\t\tvar connFlightDate = new Date(connection.STD).getTime();\r\n\r\n\t\t\tif ($scope.flightETA > connFlightDate)\r\n\t\t\t\treturn '';\r\n\r\n\t\t\tif ((connFlightDate - $scope.flightETA) < connection.MCT * 60000) {\r\n\t\t\t\treturn 'bg-bisque';\r\n\t\t\t}\r\n\r\n\t\t\tif ((connFlightDate - $scope.flightETA) < (connection.MCT + 15) * 60000) {\r\n\t\t\t\treturn 'bg-cornsilk';\r\n\t\t\t}\r\n\t\t\treturn '';\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Returns the time difference\r\n\t\t * @memberof PaxCtrl\r\n\t\t * @param {string} time Connection STD\r\n\t\t * @return {string} timeDifference\r\n\t\t */\r\n\t\tfunction TimeDifference(time) {\r\n\t\t\tvar timeString = '';\r\n\t\t\tvar sign = '';\r\n\t\t\tvar dayString = null;\r\n\r\n\t\t\tif (time) {\r\n\t\t\t\tvar connFlightDate = new Date(time);\r\n\t\t\t\tvar ms = connFlightDate.getTime() - $scope.flightETA; // this is a time in milliseconds\r\n\t\t\t\tif (ms < 0) {\r\n\t\t\t\t\tms = -ms;\r\n\t\t\t\t\tsign = \"-\";\r\n\t\t\t\t}\r\n\r\n\t\t\t\tvar days = Math.floor(ms / (24 * 60 * 60 * 1000));\r\n\t\t\t\tdays = days < 0 ? days + 1 : days;\r\n\t\t\t\tvar daysms = ms % (24 * 60 * 60 * 1000);\r\n\t\t\t\tvar hours = Math.floor((daysms) / (60 * 60 * 1000));\r\n\t\t\t\tvar hoursms = ms % (60 * 60 * 1000);\r\n\t\t\t\tvar minutes = Math.floor((hoursms) / (60 * 1000));\r\n\t\t\t\ttimeString = '' + sign + (hours > 0 ? (\"0\" + hours).substr(-2) + \":\" : '') + (\"0\" + minutes).substr(-2) + '\\'' + '';\r\n\t\t\t\tdayString = ' ' + days + 'd';\r\n\t\t\t}\r\n\t\t\treturn timeString + ((days && days != 0) ? dayString : '');\r\n\t\t}\r\n\r\n\t\tfunction attachCampaign() {\r\n\t\t\tif ($scope.paxInfo) {\r\n\t\t\t\t$scope.paxInfo.CampaignCounters = {\r\n\t\t\t\t\tpending: 0,\r\n\t\t\t\t\tcompleted: 0\r\n\t\t\t\t};\r\n\r\n\t\t\t\t$scope.paxInfo.Seatmap.forEach(function (s) {\r\n\t\t\t\t\ts.Columns.forEach(function (col) {\r\n\t\t\t\t\t\tif (col.UCI) {\r\n\t\t\t\t\t\t\tvar campaignInfo = CampaignFactory.getPaxAssignment(+flightId, col.PNR, col.UCI);\r\n\t\t\t\t\t\t\tif (campaignInfo.assignment) {\r\n\r\n\t\t\t\t\t\t\t\tcol.Campaign = JSON.parse(JSON.stringify(campaignInfo));\r\n\r\n\t\t\t\t\t\t\t\tif (col.Campaign.assignment.Status == 0)\r\n\t\t\t\t\t\t\t\t\t$scope.paxInfo.CampaignCounters.pending += 1;\r\n\r\n\t\t\t\t\t\t\t\tif (col.Campaign.assignment.Status != 0)\r\n\t\t\t\t\t\t\t\t\t$scope.paxInfo.CampaignCounters.completed += 1;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction attachLuggageCompliance() {\r\n\t\t\tif ($scope.paxInfo) {\r\n\t\t\t\t$scope.paxInfo.Seatmap.forEach(function (s) {\r\n\t\t\t\t\ts.Columns.forEach(function (col) {\r\n\t\t\t\t\t\tif (col.UCI) {\r\n\t\t\t\t\t\t\tvar opccReport = LuggageComplianceFactory.getPassengerLuggageCompliance(flightId, col.UCI);\r\n\t\t\t\t\t\t\tcol.opcc = opccReport != null\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction updateCampaignsCounters() {\r\n\t\t\t$scope.paxInfo.CampaignCounters = {\r\n\t\t\t\tpending: 0,\r\n\t\t\t\tcompleted: 0\r\n\t\t\t};\r\n\r\n\t\t\t$scope.paxInfo.Seatmap.forEach(function (s) {\r\n\t\t\t\ts.Columns.forEach(function (col) {\r\n\t\t\t\t\tif (col.Campaign) {\r\n\t\t\t\t\t\tif (col.Campaign.assignment.Status == 0) {\r\n\t\t\t\t\t\t\t$scope.paxInfo.CampaignCounters.pending += 1;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tif (col.Campaign.assignment.Status != 0) {\r\n\t\t\t\t\t\t\t$scope.paxInfo.CampaignCounters.completed += 1;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.factory('PaxInfoFactory', PaxInfoFactory);\r\n\t/**\r\n\t* @memberof CabinReports\r\n\t* @ngdoc factory\r\n\t* @name PaxInfoFactory\r\n\t* @description \r\n\t* Add, Update, Delete and Get Passenger information.\r\n\t* @ngInject\r\n\t*/\r\n\tfunction PaxInfoFactory($filter,IndexedDBService, localStorageMD5Service, SyncLogFactory, FlightFactory, CrewRouteFactory) {\r\n\r\n\t\t/**\r\n\t\t * Initialize the PaxInfo\r\n\t\t * @memberof PaxInfoFactory\r\n\t\t */\r\n\t\t//TODO EPAP :: CLEAN\r\n\t\tfunction PaxInfo() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.STD_utc = null;\r\n\t\t\tthis.STD_lcl = null;\r\n\t\t\tthis.STA_utc = null;\r\n\t\t\tthis.STA_lcl = null;\r\n\t\t\tthis.AcType = null;\r\n\t\t\tthis.Registration = null;\r\n\t\t\tthis.ConfigurationC = null;\r\n\t\t\tthis.ConfigurationY = null;\r\n\t\t\tthis.PaxTotalC = null;\r\n\t\t\tthis.PaxTotalY = null;\r\n\t\t\tthis.MarketingFlightNos = null;\r\n\t\t\tthis.SupplementaryInfo = null;\r\n\t\t\tthis.LastRun = null;\r\n\t\t\tthis.Offpoints = [];\r\n\t\t\tthis.ConnFlights = [];\r\n\t\t\tthis.Seatmap = [];\r\n\t\t\tthis.curtainRows = [];\r\n\t\t\tthis.Statistics = {};\r\n\r\n\t\t\tthis.GetId = GetId;\r\n\t\t}\r\n\r\n\t\tvar objType = 'PaxInfo';\r\n\t\tvar objCallback = PaxInfo;\r\n\r\n\t\tvar service =\r\n\t\t{\r\n\t\t\tsetPaxInfoToStorage: setPaxInfoToStorage,\r\n\t\t\tgetPaxInfoFromStorage: getPaxInfoFromStorage,\r\n\t\t\tgetPaxInfoList: getPaxInfoList,\r\n\t\t\tupdatePaxInfo: updatePaxInfo,\r\n\t\t\tgetAllPaxInfoFromStorage: getAllPaxInfoFromStorage,\r\n\t\t\tcleanOldDataPaxInfo: cleanOldDataPaxInfo,\r\n\t\t\tsetMaskPaxInfoInRoute: setMaskPaxInfoInRoute\r\n\r\n\t\t}\r\n\r\n\t\tmigratePaxInfo();\r\n\r\n\t\t/**\r\n\t * Overide default get Id\r\n\t * @memberof PaxInfoFactory\r\n\t * @returns {number} Id \r\n\t */\r\n\t\tfunction GetId() {\r\n\t\t\treturn this.FlightId;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t * Set statistics and format passenger informtion of this flight\r\n\t * @memberof PaxInfoFactory\r\n\t * @param {paxInfo} paxInfo The passenger information of a flight\r\n\t * @returns {object} statistics\r\n\t */\r\n\t\t//TODO EPAP CHANGE NAME\r\n\t\tfunction GetStatistics(paxInfo) {\r\n\t\t\tvar statistics = {};\r\n\t\t\tvar syncLog = SyncLogFactory.getSyncLog();\r\n\r\n\t\t\tif (paxInfo && paxInfo.Seatmap) {\r\n\r\n\t\t\t\tpaxInfo.curtainRows = [];\r\n\t\t\t\tvar cabinType;\r\n\t\t\t\tpaxInfo.DHC = 0;\r\n\r\n\t\t\t\tfor (var i = 0; i < paxInfo.Seatmap.length; i++) {\r\n\t\t\t\t\tfor (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\r\n\r\n\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns[j].Cabin == 'J') {\r\n\t\t\t\t\t\t\tpaxInfo.Seatmap[i].Columns[j].Cabin = 'Y';\r\n\t\t\t\t\t\t}\r\n\r\n\r\n\r\n\t\t\t\t\t\tif (cabinType == null) {\r\n\t\t\t\t\t\t\tcabinType = paxInfo.Seatmap[i].Columns[j].Cabin;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\telse if (cabinType != paxInfo.Seatmap[i].Columns[j].Cabin && paxInfo.Seatmap[i - 1] && paxInfo.Seatmap[i].Columns[j].Cabin != null) {\r\n\t\t\t\t\t\t\tcabinType = paxInfo.Seatmap[i].Columns[j].Cabin;\r\n\t\t\t\t\t\t\tpaxInfo.curtainRows.push(paxInfo.Seatmap[i - 1].RowNo);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn statistics;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Set Passenger information\r\n\t\t * @memberof PaxInfoFactory\r\n\t\t * @param {Array} paxInfos The passenger informations \r\n\t\t */\r\n\t\tfunction setPaxInfoToStorage(paxInfo, flightIds) {\r\n\t\t\tif (paxInfo) {\r\n\t\t\t\t// get paxInfo for the flights with draft reports from indexedDB (gets the new paxInfo if the flightId exists in sync response)\r\n\t\t\t\tgetAllPaxInfoFromStorage(function (paxInfoResult) {\r\n\t\t\t\t\tvar oldDraftPaxInfo = [];\r\n\t\t\t\t\tvar paxInfoFlightIds = paxInfo.map(function (item) {\r\n\t\t\t\t\t\treturn item.FlightId;\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\toldDraftPaxInfo = paxInfoResult.filter(function (item) {\r\n\t\t\t\t\t\treturn flightIds.includes(item.FlightId) &&\r\n\t\t\t\t\t\t\t!paxInfoFlightIds.includes(item.FlightId);\r\n\t\t\t\t\t});\r\n\t\t\t\t\t// get new paxInfo\r\n\t\t\t\t\tIndexedDBService.removeAll(objType).then(function () {\r\n\t\t\t\t\t\tfor (var i = 0; i < paxInfo.length; i++) {\r\n\t\t\t\t\t\t\tpaxInfo[i].Statistics = GetStatistics(paxInfo[i]);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tvar newListPaxInfo = paxInfo.concat(oldDraftPaxInfo);\r\n\t\t\t\t\t\tIndexedDBService.addAll(objType, newListPaxInfo);\r\n\r\n\t\t\t\t\t});\r\n\t\t\t\t})\r\n\r\n\t\t\t}\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clean Old Data\r\n\t\t * @memberof PaxInfoFactory\r\n\t\t * @param {Array} pendingFlightIds FlightIds with pending reports\r\n\t\t */\r\n\t\tfunction cleanOldDataPaxInfo(pendingFlightIds) {\r\n\t\t\t// get paxInfo for the flights with draft reports from indexedDB (gets the new paxInfo if the flightId exists in sync response)\r\n\t\t\tvar now = moment();\r\n\t\t\tgetAllPaxInfoFromStorage(function (paxInfoResult) {\r\n\t\t\t\tvar oldDraftPaxInfo = paxInfoResult.filter(function (item) {\r\n\t\t\t\t\treturn pendingFlightIds.includes(item.FlightId);\r\n\t\t\t\t});\r\n\t\t\t\t// keep only the pax list with pending reports\r\n\t\t\t\tIndexedDBService.removeAll(objType).then(function () {\r\n\t\t\t\t\tIndexedDBService.addAll(objType, oldDraftPaxInfo);\r\n\t\t\t\t});\r\n\t\t\t})\r\n\r\n\t\t}\r\n\t\t/**\r\n\t\t * Get Passenger information for the selected flight\r\n\t\t * @memberof PaxInfoFactory\r\n\t\t * @param {number} flightId The flight id \r\n\t\t */\r\n\t\tfunction getPaxInfoFromStorage(flightId, callback) {\r\n\t\t\t//var intFlightId = 1226541;\r\n\t\t\tvar intFlightId = +flightId;\r\n\r\n\t\t\tIndexedDBService.getById(objType, intFlightId).then(function (result) {\r\n\t\t\t\tcallback(result);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t\r\n\t\t/**\r\n\t\t * Get Passenger information list for the selected flight\r\n\t\t * @memberof PaxInfoFactory\r\n\t\t * @param {number} flightId The flight id \r\n\t\t */\r\n\t\tfunction getPaxInfoList(flightId, callback) {\r\n\t\t\tvar intFlightId = +flightId;\r\n\t\t\tvar passengerList = [];\r\n\r\n\t\t\tIndexedDBService.getById(objType, intFlightId).then(function (paxInfo) {\r\n\t\t\t\tif (paxInfo) {\r\n\t\t\t\t\tfor (var i = 0; i < paxInfo.Seatmap.length; i++) {\r\n\t\t\t\t\t\tfor (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\r\n\t\t\t\t\t\t\tvar passenger = paxInfo.Seatmap[i].Columns[j];\r\n\t\t\t\t\t\t\tif (!passenger.IsEmptySeat && passenger.SeatMode == \"Seat\") {\r\n\t\t\t\t\t\t\t\tpassengerList.push(passenger);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tcallback(passengerList);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* Get Passenger information for the selected flights\r\n\t\t* @memberof PaxInfoFactory\r\n\t\t*/\r\n\t\tfunction getAllPaxInfoFromStorage(callback) {\r\n\t\t\tIndexedDBService.getAll(objType).then(function (paxinfo) {\r\n\t\t\t\tcallback(paxinfo);\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Update Passenger information\r\n\t\t * @memberof PaxInfoFactory\r\n\t\t * @param {object} paxInfo The passenger informations \r\n\t\t */\r\n\t\tfunction updatePaxInfo(paxInfo) {\r\n\t\t\tif (paxInfo) {\r\n\t\t\t\tpaxInfo.Statistics = GetStatistics(paxInfo);\r\n\t\t\t\tIndexedDBService.put(objType, paxInfo);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Update Passenger information\r\n\t\t * @memberof PaxInfoFactory\r\n\t\t */\r\n\t\tfunction migratePaxInfo() {\r\n\t\t\tvar lsPaxInfo = localStorageMD5Service.get(objType);\r\n\t\t\tif (lsPaxInfo && lsPaxInfo.length > 0) {\r\n\t\t\t\tIndexedDBService.addAll(objType, lsPaxInfo);\r\n\t\t\t\tlocalStorageMD5Service.remove(objType);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Hide pax name with condition\r\n\t\t * @memberof PaxInfoFactory\r\n\t\t */\r\n\t\tfunction setMaskPaxInfoInRoute(flightInfo){\r\n\t\t\tif(flightInfo && flightInfo.showPaxNames){\r\n\t\t\t\tvar applyMask = false;\r\n\t\t\t\tvar flights = CrewRouteFactory.getCrewRouteFlights(flightInfo.DutyNo, flightInfo.DutyDay, flightInfo.FlightDate); \r\n\t\t\t\tflights = $filter('orderBy')(flights, 'ScheduledDeparture');\r\n\t\t\t\tvar lastFlight = flights[flights.length - 1];\r\n\t\t\t\tif(moment.utc().diff(moment(lastFlight.ATA), 'hours') > 2){\r\n\t\t\t\t\t//set mask\r\n\t\t\t\t\tapplyMask = true;\r\n\r\n\t\t\t\t} else if (moment.utc().diff(moment(lastFlight.ScheduledArrival), 'hours') > 4) {\r\n\t\t\t\t\t//set mask\r\n\t\t\t\t\tapplyMask = true;\r\n\r\n\t\t\t\t}\r\n\t\t\t\tif(applyMask){\r\n\t\t\t\t\tflights.forEach(function(flight){\r\n\t\t\t\t\t\tflight.showPaxNames = false;\r\n\t\t\t\t\t\tFlightFactory.updateFlight(flight)\r\n\t\t\t\t\t});\r\n\t\t\t\t\tvar flightIds = flights.map(function (item) {\r\n\t\t\t\t\t\treturn item.FlightId; // or Id (todo: check)\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\tsetMaskPaxInfoToStorage(flightIds);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction setMaskPaxInfoToStorage(flightIds) {\r\n\t\t\tgetAllPaxInfoFromStorage(function (paxInfoResult) {\r\n\t\t\t\tvar maskedPaxFlightList = [];\r\n\t\t\t\tmaskedPaxFlightList = paxInfoResult.filter(function (item) {\r\n\t\t\t\t\treturn flightIds.includes(item.FlightId);\r\n\t\t\t\t});\r\n\t\t\t\tfor (var i = 0; i < maskedPaxFlightList.length; i++) {\r\n\t\t\t\t\tmaskPaxNames(maskedPaxFlightList[i]);\r\n\t\t\t\t}\r\n\t\t\t\tvar otherPaxInfo = paxInfoResult.filter(function (item) {\r\n\t\t\t\t\treturn !flightIds.includes(item.FlightId);\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// get new paxInfo\r\n\t\t\t\tIndexedDBService.removeAll(objType).then(function () {\r\n\t\t\t\t\tvar newListPaxInfo = otherPaxInfo.concat(maskedPaxFlightList);\r\n\t\t\t\t\tIndexedDBService.addAll(objType, newListPaxInfo);\r\n\t\t\t\t});\r\n\t\t\t})\r\n\t\t}\r\n\r\n\t\tfunction maskPaxNames(pax){\r\n\t\t\tif (pax) {\r\n\t\t\t\tfor (var i = 0; i < pax.Seatmap.length; i++) {\r\n\t\t\t\t\tfor (var j = 0; j < pax.Seatmap[i].Columns.length; j++) {\r\n\t\t\t\t\t\tvar passenger = pax.Seatmap[i].Columns[j];\r\n\t\t\t\t\t\tif (!passenger.IsEmptySeat && passenger.SeatMode == \"Seat\") {\r\n\t\t\t\t\t\t\tpassenger.InfantName = passenger.InfantSurname ? \"*****\" : passenger.InfantSurname;\r\n\t\t\t\t\t\t\tpassenger.InfantGivenName = passenger.InfantGivenName ? \"*****\" : passenger.InfantGivenName;\r\n\t\t\t\t\t\t\tpassenger.Fullname = passenger.Fullname ? \"***** *****\" : passenger.Fullname;\r\n\t\t\t\t\t\t\tpassenger.Surname = passenger.Surname ? \"*****\" : passenger.Surname;\r\n\t\t\t\t\t\t\tpassenger.GivenName = passenger.GivenName ? \"*****\" : passenger.GivenName;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('toolkit', toolkit);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name toolkit\r\n * @restrict E\r\n * @description\r\n * Implementation of toolkit\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function toolkit($timeout, ToolkitFactory, CustomerEventFactory) { \r\n function link(scope) {\r\n scope.closeAlert = closeAlert;\r\n scope.goBack = goBack;\r\n \r\n scope.removeCustomerEvent = removeCustomerEvent;\r\n scope.addEditIncident = addEditIncident;\r\n scope.isRedeemed = false;\r\n scope.getIsRedeemed = getIsRedeemed;\r\n scope.submitCustomerEvent = submitCustomerEvent;\r\n scope.toggleDeleteAlert = toggleDeleteAlert;\r\n scope.validForm = validForm;\r\n scope.emailFormat = /^[a-zA-Z]+[a-zA-Z0-9._]+@[a-zA-Z]+\\.[a-zA-Z.]{2,5}$/;\r\n scope.mobileFormat = /^[\\+]?[(]?[0-9]{3}[)]?[-\\s\\.]?[0-9]{3}[-\\s\\.]?[0-9]{4,6}$/im;\r\n scope.FQTVNumber = scope.passenger.Fqtv && scope.passenger.Fqtv.Carrier == \"A3\"? scope.passenger.Fqtv.Number : null;\r\n\r\n setupToolkit();\r\n function setupToolkit(){\r\n initializeToolkit(scope.passenger, function(toolKitItems){\r\n scope.toolkit = toolKitItems;\r\n scope.customerEvents = getCustomerEvents(toolKitItems, scope.flight.FlightId, scope.passenger.UCI);\r\n if(scope.toolkit.some(x => x.Treatments.length)){\r\n scope.treatmentAvailability({counter:scope.customerEvents.length});\r\n }\r\n \r\n if(scope.customerEvents.length>0){\r\n scope.isListView = true;\r\n scope.isEdit = false;\r\n }\r\n else{\r\n addEditIncident();\r\n } \r\n });\r\n }\r\n\r\n\r\n /**\r\n * Save Customer Event in local storage\r\n */\r\n function submitCustomerEvent(){\r\n var customerEvent = {\r\n ToolkitItemId : scope.newForm.selectedIncident.Id,\r\n TreatmentId : scope.newForm.selectedTreatment,\r\n PNR : scope.passenger.PNR,\r\n UCI : scope.passenger.UCI,\r\n FQTVNumber : scope.FQTVNumber,\r\n FQTVTierLevel : scope.passenger.Fqtv && scope.passenger.Fqtv.Carrier == \"A3\" ? scope.passenger.Fqtv.TierLevel : null,\r\n NPS : scope.newForm.NPS,\r\n Comments : scope.newForm.CrewComments,\r\n FlightId : scope.flight.FlightId,\r\n FlightNo : scope.flight.FlightNo,\r\n Departure : scope.flight.Departure,\r\n Arrival : scope.flight.Arrival,\r\n FlightDate : scope.flight.FlightDate,\r\n Email : scope.newForm.passengerEmail,\r\n TelephoneCode : scope.newForm.telephoneCode,\r\n Mobile : scope.newForm.passengerMobile,\r\n ContactLanguage : scope.newForm.contactLanguage,\r\n GivenName : scope.passenger.GivenName,\r\n Surname : scope.passenger.Surname,\r\n SeatNo : scope.passenger.SeatNo,\r\n ClassOfService: scope.passenger.Cabin,\r\n LocalId: scope.newForm.LocalId ? scope.newForm.LocalId : moment().valueOf() \r\n };\r\n \r\n CustomerEventFactory.setCustomerEventToStorage(customerEvent);\r\n\r\n goBack();\r\n scope.isIncidentUpdated = true;\r\n $timeout(function () {\r\n scope.isIncidentUpdated = false;\r\n }, 5000);\r\n }\r\n\r\n /**\r\n * Add or update a customer event\r\n * @param {object} customerEvent Selected customer event from list (edit mode)\r\n */\r\n function addEditIncident(customerEvent){\r\n scope.toolkitOptions = scope.toolkit.filter(x => !scope.customerEvents.some(y => y.Id == x.Id) && !x.Fallback).concat(scope.toolkit.filter(x => x.Fallback));\r\n scope.newForm={\r\n selectedIncident : null,\r\n selectedTreatment : null,\r\n passengerEmail : null,\r\n contactLanguage: \"EN\",\r\n telephoneCode : \"30\", //Defaut value GR\r\n passengerMobile: null,\r\n NPS: null,\r\n CrewComments: null\r\n };\r\n\r\n scope.isEdit = customerEvent == null || customerEvent == undefined;\r\n\r\n if(customerEvent){\r\n scope.newForm={\r\n selectedIncident : customerEvent,\r\n selectedTreatment : customerEvent.CustomerEvent.TreatmentId,\r\n passengerEmail : customerEvent.CustomerEvent.Email,\r\n telephoneCode : customerEvent.CustomerEvent.TelephoneCode,\r\n passengerMobile : customerEvent.CustomerEvent.Mobile,\r\n contactLanguage : customerEvent.CustomerEvent.ContactLanguage,\r\n NPS : customerEvent.CustomerEvent.NPS,\r\n CrewComments : customerEvent.CustomerEvent.Comments,\r\n LocalId : customerEvent.CustomerEvent.LocalId\r\n };\r\n\r\n if(!scope.toolkitOptions.some(x => x.Id == customerEvent.Id)){\r\n scope.toolkitOptions.push(scope.toolkit.find(x => x.Id == customerEvent.Id));\r\n }\r\n }\r\n \r\n scope.isListView = false; //Change view\r\n }\r\n \r\n /**\r\n * Gets treatment redeem\r\n */\r\n function getIsRedeemed(item){\r\n scope.isRedeem = scope.toolkitOptions.flatMap(x => x.Treatments).filter(s => s.Id == item).map(f => f.IsRedeemed)[0];\r\n }\r\n\r\n /**\r\n * Go to Toolkit Items list view\r\n */\r\n function goBack(){\r\n scope.isIncidentUpdated = false;\r\n scope.deleteAlert = false;\r\n scope.isListView = true;\r\n scope.isEdit = false;\r\n scope.newForm = null;\r\n setupToolkit();\r\n }\r\n\r\n /**\r\n * Validate form before saving\r\n */\r\n function validForm(){\r\n // 1. Has a treatment selected\r\n // 2. Has NPS Score selected\r\n // 3. Has passenger email when nqtvNo is null or ( email or mobile is not null) \r\n \r\n var validForm = false;\r\n var form = scope.newForm;\r\n \r\n if(form){\r\n validForm = form.selectedIncident && form.selectedTreatment && form.NPS \r\n && (scope.FQTVNumber && (form.passengerEmail || form.passengerMobile) \r\n || (!scope.FQTVNumber && form.passengerEmail));\r\n }\r\n \r\n return validForm;\r\n }\r\n\r\n /**\r\n * Remove Customer Event from local storage\r\n */\r\n function removeCustomerEvent(){\r\n CustomerEventFactory.removeCustomerEvent(scope.newForm.LocalId);\r\n \r\n scope.treatmentAvailability({counter:scope.customerEvents.length});\r\n goBack();\r\n }\r\n\r\n /**\r\n * Close successful save alert\r\n */\r\n function closeAlert(){\r\n scope.isIncidentUpdated = false;\r\n }\r\n\r\n function toggleDeleteAlert(){\r\n scope.deleteAlert = !scope.deleteAlert;\r\n }\r\n }\r\n\r\n var passengerCategories = {\r\n none: 0,\r\n gold : 1,\r\n business : 2,\r\n silver : 3,\r\n blue : 4,\r\n economy: 5\r\n };\r\n\r\n /**\r\n * Gets all toolkit items and filter treatments depending on passenger's class\r\n * @param {object} passenger \r\n * @param {function} callback \r\n */\r\n function initializeToolkit(passenger, callback){\r\n ToolkitFactory.getToolkitItemsFromStorage(function(toolKitItems){\r\n var paxCategories = getPaxCategories(passenger);\r\n toolKitItems.forEach(function(item){\r\n var matchingCategories = paxCategories.some(function(category) {\r\n return item.TouchpointCategories.includes(category);\r\n });\r\n var treatmentGroups = item.Treatments.groupByKey(\"PaxCategory\");\r\n \r\n if(matchingCategories && paxCategories.contains(passengerCategories.gold) && treatmentGroups[passengerCategories.gold]){\r\n item.Treatments = treatmentGroups[passengerCategories.gold];\r\n }\r\n else if(matchingCategories && paxCategories.contains(passengerCategories.business) && treatmentGroups[passengerCategories.business]){\r\n item.Treatments = treatmentGroups[passengerCategories.business];\r\n }\r\n else if(matchingCategories && paxCategories.contains(passengerCategories.silver) && treatmentGroups[passengerCategories.silver]){\r\n item.Treatments = treatmentGroups[passengerCategories.silver];\r\n }\r\n else if(matchingCategories && paxCategories.contains(passengerCategories.blue) && treatmentGroups[passengerCategories.blue]){\r\n item.Treatments = treatmentGroups[passengerCategories.blue];\r\n }\r\n else if(matchingCategories && paxCategories.contains(passengerCategories.economy) && treatmentGroups[passengerCategories.economy]){\r\n item.Treatments = treatmentGroups[passengerCategories.economy];\r\n }\r\n else{\r\n //No available treatments for this passenger\r\n item.Treatments = [];\r\n }\r\n \r\n if(item.Treatments.length){\r\n //Add 'No Treatment'\r\n item.Treatments = item.Treatments.concat(treatmentGroups[passengerCategories.none])\r\n }\r\n });\r\n \r\n\r\n //Toolkit Items without treatments should not be visible\r\n toolKitItems = toolKitItems.filter(t => t.Treatments && t.Treatments.length);\r\n callback(toolKitItems);\r\n });\r\n }\r\n \r\n function getPaxCategories(passenger){\r\n var passengerClass = passenger.Cabin;\r\n var passengerFqtv = passenger.Fqtv && passenger.Fqtv.Carrier == \"A3\" ? passenger.Fqtv.TierDescription.toLowerCase() : null;\r\n\r\n var paxCategories = [];\r\n\r\n if(passengerClass == 'C'){\r\n paxCategories.push(passengerCategories.business);\r\n }\r\n if(passengerFqtv == 'gold'){\r\n paxCategories.push(passengerCategories.gold);\r\n }\r\n else if(passengerFqtv == 'silver'){\r\n paxCategories.push(passengerCategories.silver);\r\n }\r\n else if(passengerFqtv == 'blue'){\r\n paxCategories.push(passengerCategories.blue);\r\n }\r\n else if(passengerClass == 'Y'){\r\n paxCategories.push(passengerCategories.economy);\r\n }\r\n\r\n return paxCategories;\r\n }\r\n\r\n /**\r\n * Get customer events by flightId and UCI and attach them to their toolkitItem\r\n * @param {array} toolKitItems \r\n * @param {number} flightId \r\n * @param {number} UCI \r\n */\r\n function getCustomerEvents(toolKitItems, flightId, UCI){\r\n var customerEvents=[];\r\n //All events created for this passenger & on this flight\r\n var storedCustomerEvents = CustomerEventFactory.getFlightCustomerEvents(flightId, UCI);\r\n \r\n storedCustomerEvents.forEach(function(customerEvent){\r\n var item = JSON.parse(JSON.stringify( toolKitItems.find(x => x.Id == customerEvent.ToolkitItemId) ));\r\n item.CustomerEvent = customerEvent;\r\n customerEvents.push(item);\r\n });\r\n return customerEvents;\r\n }\r\n\r\n \r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/OneStopShop/toolkit.tpl.html',\r\n scope: { flight:\"=\", passenger:\"=\", treatmentAvailability : \"&onTreatmentAvailability\"},\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n a3_cabin_reports.directive('philoxeniaQuestions', philoxeniaQuestions);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name philoxeniaQuestions\r\n * @restrict E\r\n * @description\r\n * Implementation of philoxenia questions \r\n *\r\n * Display the philoxenia questions Panel\r\n * @attr {String} flight-id\r\n * @example\r\n * Usage:\r\n * \r\n * \r\n * @ngInject\r\n */\r\n function philoxeniaQuestions(PhiloxeniaQuestionsFactory){\r\n /**\r\n * Initialize philoxeniaQuestions\r\n * @memberof philoxeniaQuestions\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\r\n function link(scope, element, attributes) {\r\n scope.togglePanel = togglePanel;\r\n scope.hasPhiloxeniaData = true;\r\n scope.philoxeniaData = null;\r\n scope.showPanel = showPanel();\r\n\r\n initializePanel();\r\n\r\n /**\r\n * Initialize Form Values\r\n * @memberof philoxeniaQuestions\r\n */\r\n function initializePanel(){\r\n var flightQuestions = PhiloxeniaQuestionsFactory.getFlightPhiloxeniaQuestionsFromStorage(+scope.flightId);\r\n \r\n if(!flightQuestions || !flightQuestions.Questions > 0 || !flightQuestions.RepliesCounter > 0){\r\n scope.hasPhiloxeniaData = false;\r\n }\r\n else{\r\n scope.hasPhiloxeniaData = true;\r\n scope.philoxeniaData = flightQuestions;\r\n }\r\n }\r\n \r\n function showPanel(){\r\n var retVal = false;\r\n var now = moment.utc();\r\n var std = moment.utc(scope.std); \r\n var isAfter = now.isAfter(std);\r\n\r\n if(isAfter ){\r\n retVal = true;\r\n }\r\n \r\n return retVal;\r\n \r\n }\r\n\r\n /**\r\n * Toggle Panel\r\n * @memberof philoxeniaQuestions\r\n * @param {number} panelId\r\n */\r\n function togglePanel(panelId) {\r\n $('#' + panelId).toggle();\r\n }\r\n\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: true,\r\n templateUrl: 'views/directives/philoxeniaQuestions.tpl.html',\r\n scope: {\r\n flightId: '@',\r\n std:'@'\r\n },\r\n link: link\r\n }\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('PhiloxeniaQuestionsFactory', PhiloxeniaQuestionsFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PhiloxeniaQuestionsFactory\r\n * @ngInject\r\n */\r\n function PhiloxeniaQuestionsFactory(GenericService) {\r\n function PhiloxeniaQuestions() {\r\n this.FlightId = null;\r\n this.Questions = null;\r\n this.RepliesCounter = 0;\r\n\r\n\t\t}\r\n\r\n var objType ='philoxeniaQuestions';\r\n\t\tvar objCallback = PhiloxeniaQuestions; \r\n \r\n var ratingQuestions = [{Option: 1, OptionText: \"Basic\", Counter: 0, Percentage: null},\r\n {Option: 2, OptionText: \"Basic +\", Counter: 0, Percentage: null},\r\n {Option: 3, OptionText: \"Expected\", Counter: 0, Percentage: null},\r\n {Option: 4, OptionText: \"Expected +\", Counter: 0, Percentage: null},\r\n {Option: 5, OptionText: \"Excellent\", Counter: 0, Percentage: null} ];\r\n\r\n var service = {\r\n updatePhiloxeniaQuestionsToStorage : updatePhiloxeniaQuestionsToStorage,\r\n getFlightPhiloxeniaQuestionsFromStorage : getFlightPhiloxeniaQuestionsFromStorage,\r\n cleanOldData: cleanOldData\r\n };\r\n\r\n /**\r\n * Get Philoxenia Questions.\r\n * @memberof PhiloxeniaQuestionsFactory\r\n * @returns {Array} PhiloxeniaQuestions \r\n */\r\n\t\tfunction getPhiloxeniaQuestionsFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save Philoxenia Questions to storage\r\n * @memberof PhiloxeniaQuestionsFactory\r\n * @param {Array} PhiloxeniaQuestions\r\n */\r\n\t\tfunction setPhiloxeniaQuestionsToStorage(objList) {\r\n\t\t\tGenericService.saveAll(objList,objType);\r\n }\r\n\r\n /**\r\n * Update Philoxenia Questions for specified flight\r\n * @memberof PhiloxeniaQuestionsFactory\r\n * @param {} PhiloxeniaQuestions questions for a flight\r\n * @returns {Array} PhiloxeniaQuestions\r\n */\r\n function updatePhiloxeniaQuestionsToStorage(philoxeniaQuestions){\r\n //Get all PhiloxeniaQuestions exept current flight from storage\r\n var storedPhiloxeniaQuestions = getPhiloxeniaQuestionsFromStorage();\r\n var storedPhiloxeniaQuestionsFiltered = storedPhiloxeniaQuestions.filter(f=> f != null && f.FlightId != philoxeniaQuestions.FlightId);\r\n //Add Philoxenia Questions for the current flight\r\n if(philoxeniaQuestions){\r\n //get AVG value for Rating questions\r\n philoxeniaQuestions.Questions.forEach(function(question){\r\n if(question.QuestionInfo.Type == \"RATING\"){\r\n //Get Option List\r\n var optionList = [];\r\n ratingQuestions.forEach(function(option){\r\n var currentAnswer = question.AnswerCounters.filter(f=> f.OptionId == option.Option);\r\n if(currentAnswer.length>0 && philoxeniaQuestions.RepliesCounter>0){\r\n option.Counter = currentAnswer[0].Counter;\r\n option.Percentage = (currentAnswer[0].Counter / philoxeniaQuestions.RepliesCounter)*100;\r\n }\r\n optionList.push(option);\r\n })\r\n question.OptionList = optionList;\r\n\r\n //Get AVG value\r\n var value = 0;\r\n var weight = 0;\r\n question.AnswerCounters.forEach(function(answer){\r\n value += +answer.TextValue * answer.Counter;\r\n weight += answer.Counter;\r\n })\r\n if(weight > 0){\r\n question.AVG = value / weight;\r\n }\r\n }\r\n else{\r\n var selectedOptionIds = question.AnswerCounters.map(function(v){\r\n return v.OptionId;\r\n });\r\n\r\n //get AnswerCounter for selections with zero counter\r\n var optionsZeroCounter = question.QuestionInfo.Options.filter(x => !selectedOptionIds.includes(x.Id));\r\n var optionsZeroCounterMapper = optionsZeroCounter.map(function(a){\r\n return {OptionId:a.Id, TextValue:a.Value, Counter:0}\r\n })\r\n\r\n question.AnswerCounters = question.AnswerCounters.concat(optionsZeroCounterMapper);\r\n question.AVG = 0;\r\n }\r\n });\r\n //Get only questions with answers\r\n philoxeniaQuestions.Questions = philoxeniaQuestions.Questions.filter(f=>f.AnswerCounters && f.AnswerCounters.length>0);\r\n \r\n storedPhiloxeniaQuestionsFiltered.push(philoxeniaQuestions);\r\n //save PhiloxeniaQuestions\r\n setPhiloxeniaQuestionsToStorage(storedPhiloxeniaQuestionsFiltered);\r\n }\r\n }\r\n\r\n /**\r\n * Get Philoxenia Questions for specified flight\r\n * @memberof PhiloxeniaQuestionsFactory\r\n * @param {number} flightId\r\n * @returns {Array} PhiloxeniaQuestions\r\n */\r\n\t\tfunction getFlightPhiloxeniaQuestionsFromStorage(flightId) {\r\n\t\t\tvar storedPhiloxeniaQuestions = getPhiloxeniaQuestionsFromStorage();\r\n if(storedPhiloxeniaQuestions){\r\n var flightPhiloxeniaQuestions = storedPhiloxeniaQuestions.filter(x => x != null && x.FlightId == flightId);\r\n return flightPhiloxeniaQuestions[0];\r\n }else{\r\n return null;\r\n }\r\n \r\n\t\t}\r\n\r\n\r\n /**\r\n * Clean ls from old flights Philoxenia Questions\r\n * @param {array} flights Synced flights\r\n */\r\n function cleanOldData(responseFlightIds){\r\n var previousPhiloxeniaQuestions = getPhiloxeniaQuestionsFromStorage();\r\n \r\n //Filter out Philoxenia Questions of old flights\r\n previousPhiloxeniaQuestions = previousPhiloxeniaQuestions.filter(x => x != null && responseFlightIds.includes(x.FlightId));\r\n \r\n setPhiloxeniaQuestionsToStorage(previousPhiloxeniaQuestions);\r\n }\r\n\r\n return service;\r\n }\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.factory('CabinReportLocalEditFactory', CabinReportLocalEditFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportLocalEditFactory\r\n * @description \r\n * Manage Local Cabin Reports.\r\n * @ngInject\r\n */\r\n\tfunction CabinReportLocalEditFactory($log, localStorageMD5Service, CCMSFactory, LogService, UserFactory, GenericService, GroundServicesFactory,BarTrolleyFactory, enableWaterUpliftReporting, waterUpliftSupportingAcTypes) {\r\n\r\n /**\r\n * Initialiaze CabinReportLocalEdit object \r\n * @memberof CabinReportLocalEditFactory\r\n */\r\n\t\tfunction CabinReportLocalEdit() {\r\n\t\t\tthis.ReportGuid = null;\r\n\t\t\tthis.AuthorId = null;\r\n\t\t\tthis.AuthorAimsId = null;\r\n\t\t\tthis.AuthorName = null;\r\n\t\t\tthis.Created = null;\r\n\t\t\tthis.FlightAimsId = null;\r\n\t\t\tthis.FlightId = null;\r\n\t\t\tthis.LastUpdated = null;\r\n\t\t\tthis.Departure = null;\r\n\t\t\tthis.Arrival = null;\r\n\t\t\tthis.AcType = null;\r\n\t\t\tthis.AcTailNo = null;\r\n\t\t\tthis.FlightDate = null;\r\n\t\t\tthis.FlightNo = null;\r\n\t\t\t//v1.1 added pax and dep/arr details\r\n\t\t\tthis.BookedC = null;\r\n\t\t\tthis.BookedY = null;\r\n\t\t\tthis.BookedInf = null;\r\n\t\t\tthis.BookedPad = null;\r\n\t\t\tthis.BookedChld = null;\r\n\t\t\tthis.ActualC = null;\r\n\t\t\tthis.ActualY = null;\r\n\t\t\tthis.ActualInf = null;\r\n\t\t\tthis.ActualPad = null;\r\n\t\t\tthis.ActualChld = null;\r\n\t\t\tthis.DepartureICAO = null;\r\n\t\t\tthis.DepartureCountry = null;\r\n\t\t\tthis.DepartureName = null;\r\n\t\t\tthis.ArrivalICAO = null;\r\n\t\t\tthis.ArrivalCountry = null;\r\n\t\t\tthis.ArrivalName = null;\r\n\t\t\tthis.ScheduledDeparture = null;\r\n\t\t\tthis.ScheduledDepartureDateUTC = null;\r\n\t\t\tthis.ScheduledDepartureTimeUTC = null;\r\n\t\t\tthis.Departure = null;\r\n\t\t\tthis.Arrival = null;\r\n\t\t\tthis.ReportId = null;\r\n\t\t\tthis.Status = null; // pending, draft, completed, synched\r\n\t\t\tthis.IsValid = false;\r\n\r\n\t\t\t//new fields\r\n\t\t\tthis.DepartureGate = null;\r\n\t\t\tthis.DepartureTimezone = null;\r\n\t\t\tthis.ArrivalTimezone = null;\r\n\t\t\tthis.CallSign = null;\r\n\t\t\tthis.ScheduledArrival = null;\r\n\t\t\tthis.ActiveVariousIssues = 0;\r\n\t\t\tthis.WarningVariousIssues = 0;\r\n\t\t\tthis.CCMSCrewPositions = [];\r\n\t\t\tthis.CCMSCrewPositionsIsValid = false;\r\n\t\t\tthis.CCMSCrewPositionsErrorMessage = null;\r\n\t\t\tthis.FlightReportSubmittedBy1L = true;\r\n\t\t\tthis.CrewRemarks = null;\r\n\t\t\tthis.ItemsFoundDescription = null;\r\n\t\t\tthis.ItemsFoundAgent = null;\r\n\t\t\tthis.ItemsFoundSignature = null;\r\n\t\t\tthis.ItemsFoundSectionHasValue = false;\r\n\t\t\tthis.ItemsFoundSectionIsValid = false;\r\n\t\t\tthis.UMNumber = 0;\r\n\t\t\tthis.UMDescription = null;\r\n\t\t\tthis.UMAgent = null;\r\n\t\t\tthis.UMSignature = null;\r\n\t\t\tthis.UMSectionHasValue = false;\r\n\t\t\tthis.UMSectionIsValid = false;\r\n\t\t\tthis.WaterUpliftSuggestedQuantity = null;\r\n\t\t\tthis.WaterUpliftInitial = null;\r\n\t\t\tthis.WaterUpliftRemarks = null;\r\n\t\t\tthis.WaterSectionHasValue = false;\r\n\t\t\tthis.WaterSectionIsValid = false;\r\n\t\t\tthis.GroundServicesSectionHasValue = false;\r\n\t\t\tthis.BarTrolleys = [];\r\n\t\t\tthis.BarTrolleysIsValid = false;\r\n\t\t\tthis.FirstAidKits = [];\r\n\t\t\tthis.FirstAidKitsIsValid = [];\r\n\t\t\tthis.MedicalIncidents = [];\r\n\t\t\tthis.MedicalIncidentsIsValid = [];\r\n\t\t\tthis.SpecialMealIssues = [];\r\n\t\t\tthis.SpecialMealIssuesIsValid = false;\r\n\t\t\tthis.Supplies = [];\r\n\t\t\tthis.SuppliesIsValid = false;\r\n\t\t\tthis.SuppliesErrorMessage = null;\r\n\t\t\tthis.TravelValueSeals = [];\r\n\t\t\tthis.TravelValueSealsIsValid = false;\r\n\t\t\tthis.TravelValueIncomplete = false;\r\n\t\t\tthis.TravelValueIncompleteRow = null;\r\n\t\t\tthis.TravelValueIncompleteReason = null;\r\n\t\t\tthis.TravelValueRemarks = null;\r\n\t\t\tthis.Remarks = null;\r\n\t\t\tthis.VariousIssues = [];\r\n\t\t\t//v1.1 :: used to hold all crew (fd, cabin & dhc)\r\n\t\t\tthis.crew = null;\r\n\t\t\tthis.Route = null;\r\n\t\t\tthis.DutyDate = null;\r\n\t\t\tthis.getDescription = getDescription;\r\n\t\t\tthis.getRoute = getRoute;\r\n\t\t\tthis.updateTotals = updateTotals;\r\n\t\t\tthis.validateCCMS = validateCCMS;\r\n\t\t\tthis.getCCMSObj = getCCMSObj;\r\n\t\t\tthis.saveReport = saveReport;\r\n\t\t\tthis.saveReportAsTemp = saveReportAsTemp;\r\n\t\t\tthis.getRemaining = getRemaining;\r\n\t\t\tthis.ArrivalGroundServices = [];\r\n\t\t\tthis.DepartureGroundServices = [];\r\n\t\t\tthis.UpgradedPassengers = [];\r\n\t\t\tthis.ChangedSeats = [];\r\n\t\t\tthis.IncompleteServices = [];\r\n\t\t\tthis.IncompleteServicesIsValid = false;\r\n\t\t\t//this.BoardingTimes = null;\r\n\t\t\tthis.BoardingTimesRemarks = null;\r\n\t\t\tthis.FirstPaxTime = null;\r\n\t\t\tthis.LastPaxTime = null;\r\n\t\t\tthis.showBarTrolleyUploadImage = true;\r\n\t\t\tthis.showBarTrolleyInsertData = true;\r\n\t\t\tthis.disableBarTrolleysPhotoRemarks = true;\r\n\t\t\tthis.LuggageNumber = 0;\r\n\t\t\tthis.LuggageDescription = null;\r\n\r\n\t\t\tthis.GetId = GetId;\r\n\r\n\t\t\tthis.GroomingReports = [];\r\n\t\t}\r\n\t\tvar objType = 'cabinReportLocalEdits';\r\n\t\tvar objCallback = CabinReportLocalEdit;\r\n\r\n\t\tvar service = {\r\n\t\t\tfromObject: fromObject,\r\n\t\t\tfromObjectList: fromObjectList,\r\n\t\t\tgetCabinReportsFromStorage: getCabinReportsFromStorage,\r\n\t\t\tsetCabinReportsToStorage: setCabinReportsToStorage,\r\n\t\t\tdeleteTempReport: deleteTempReport,\r\n\t\t\tgetPreviousCabinReportCcmsPositions: getPreviousCabinReportCcmsPositions,\r\n\t\t\tdeleteReport: deleteReport,\r\n\t\t\tsetCabinReportToStorage: setCabinReportToStorage,\r\n\t\t\tgetCabinReportLocalEditFromTemp: getCabinReportLocalEditFromTemp,\r\n\t\t\tgetCabinReportLocalEditForFlight: getCabinReportLocalEditForFlight,\r\n\t\t\tgetCabinReportLocalEdit: getCabinReportLocalEdit,\r\n\t\t\tgetCabinReportLocalEditCountThatNeedToBeSynched: getCabinReportLocalEditCountThatNeedToBeSynched,\r\n\t\t\tIsExistForRouteDutyDate: IsExistForRouteDutyDate,\r\n\t\t\tgetCabinReportLocalEditThatNeedToBeSynched: getCabinReportLocalEditThatNeedToBeSynched,\r\n\t\t\tgetNewReport: getNewReport,\r\n\t\t\tmarkReportAsSynched: markReportAsSynched,\r\n\t\t\tcheckForNewGroundServices: checkForNewGroundServices,\r\n\t\t\tgetFlightIdsWithPendingReports: getFlightIdsWithPendingReports,\r\n\t\t\tgetGroomingReports: getGroomingReports\r\n\t\t}\r\n\r\n\t\tfunction getGroomingReports() {\r\n\t\t\tvar allReports = getCabinReportsFromStorage();\r\n\t\t\tvar groomingReports = [];\r\n\t\t\r\n\t\t\tallReports.forEach(report => {\r\n\t\t\t\tif (report.GroomingReports) {\r\n\t\t\t\t\treport.GroomingReports.forEach(groomingReport => {\r\n\t\t\t\t\t\tif (!groomingReport.isSynced) {\r\n\t\t\t\t\t\t\tgroomingReports.push({\r\n\t\t\t\t\t\t\t\treportGuid: report.ReportGuid,\r\n\t\t\t\t\t\t\t\tcrewId: groomingReport.crewId,\r\n\t\t\t\t\t\t\t\tgroomingCategoryId: groomingReport.groomingCategoryId,\r\n\t\t\t\t\t\t\t\tfeedback: groomingReport.feedback,\r\n\t\t\t\t\t\t\t\tisSynced: groomingReport.isSynced,\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t\r\n\t\t\treturn groomingReports;\r\n\t\t}\r\n\r\n /**\r\n * Overide default get Id\r\n * @memberof CabinReportLocalEditFactory\r\n * @returns {string} ReportGuid \r\n */\r\n\t\tfunction GetId() {\r\n\t\t\treturn this.ReportGuid;\r\n\t\t}\r\n\r\n /**\r\n * Get a short Description of this cabin report\r\n * @memberof CabinReportLocalEditFactory\r\n * @returns {string} Description \r\n */\r\n\t\tfunction getDescription() {\r\n\t\t\tvar s = this.FlightNo + ' ' + this.Departure + '-' + this.Arrival + ' ' + this.ScheduledDepartureDateUTC + ' by ' + this.AuthorName;\r\n\t\t\treturn s;\r\n\t\t}\r\n\r\n /**\r\n * Get the Route of this cabin report\r\n * @memberof CabinReportLocalEditFactory\r\n * @returns {string} Route \r\n */\r\n\t\tfunction getRoute() {\r\n\t\t\tif (this.Departure == null && this.Arrival == null) return '-';\r\n\t\t\telse return (this.Departure || '?') + '-' + (this.Arrival || '?');\r\n\t\t}\r\n\r\n /**\r\n * Update the totals of all the section of the report\r\n * @memberof CabinReportLocalEditFactory\r\n */\r\n\t\tfunction updateTotals() {\r\n\t\t\t// check the various issues\r\n\t\t\tvar allActiveVariousIssues = 0;\r\n\t\t\tvar allWarningVariousIssues = 0;\r\n\r\n\t\t\tvar variousItemCount = this.VariousIssues.length;\r\n\t\t\tfor (var i = 0; i < variousItemCount; i++) {\r\n\r\n\t\t\t\tif (this.VariousIssues[i].ItemHasValue == true) {\r\n\r\n\t\t\t\t\tif ((this.VariousIssues[i].ItemValue != null) &&\r\n\t\t\t\t\t\t(this.VariousIssues[i].ItemValue != '')) {\r\n\t\t\t\t\t\tallActiveVariousIssues++;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tallWarningVariousIssues++;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tthis.ActiveVariousIssues = allActiveVariousIssues;\r\n\t\t\tthis.WarningVariousIssues = allWarningVariousIssues;\r\n\t\t\t// check if the report is valid\r\n\t\t\tthis.IsValid = true;\r\n\r\n\t\t\t// various issues\r\n\t\t\tif (this.WarningVariousIssues > 0) {\r\n\t\t\t\tthis.IsValid = false;\r\n\t\t\t}\r\n\r\n\r\n\t\t\t// ccms crew positions\r\n\t\t\tthis.CCMSCrewPositionsIsValid = true;\r\n\t\t\tfor (var i = 0; i < this.CCMSCrewPositions.length; i++) {\r\n\t\t\t\tif ((this.CCMSCrewPositions[i].CrewId == null) || (this.CCMSCrewPositions[i].CrewId == '') ||\r\n\t\t\t\t\t/*(this.CCMSCrewPositions[i].Initials == null) || (this.CCMSCrewPositions[i].Initials == '') ||*/ //AIMS has crew with empty 3ltr code\r\n\t\t\t\t\t(this.CCMSCrewPositions[i].Name == null) || (this.CCMSCrewPositions[i].Name == '') ||\r\n\t\t\t\t\t(this.CCMSCrewPositions[i].Position == null) || (this.CCMSCrewPositions[i].Position == '')) {\r\n\t\t\t\t\tthis.IsValid = false;\r\n\t\t\t\t\tthis.CCMSCrewPositionsIsValid = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (!this.validateCCMS()) {\r\n\t\t\t\tthis.IsValid = false;\r\n\t\t\t\tthis.CCMSCrewPositionsIsValid = false;\r\n\t\t\t}\r\n\r\n\t\t\tthis.FlightReportSubmittedBy1L = false;\r\n\t\t\tvar user = UserFactory.getUser();\r\n\t\t\tif (user.position == \"FA\") {\r\n\t\t\t\tthis.FlightReportSubmittedBy1L = true;\r\n\t\t\t} else {\r\n\t\t\t\tfor (var i = 0; i < this.CCMSCrewPositions.length; i++) {\r\n\t\t\t\t\tif (user.aimsId == this.CCMSCrewPositions[i].CrewId && (this.CCMSCrewPositions[i].CCMS == \"1L\" || this.CCMSCrewPositions[i].CCMS == null || this.CCMSCrewPositions[i].CCMS == \"\")) {\r\n\t\t\t\t\t\tthis.FlightReportSubmittedBy1L = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// items found\r\n\t\t\tthis.ItemsFoundSectionIsValid = true;\r\n\t\t\tthis.ItemsFoundSectionHasValue = false;\r\n\t\t\tif (((this.ItemsFoundDescription != null) && (this.ItemsFoundDescription != '')) ||\r\n\t\t\t\t((this.ItemsFoundAgent != null) && (this.ItemsFoundAgent != '')) ||\r\n\t\t\t\t((this.ItemsFoundSignature != null) && (this.ItemsFoundSignature != ''))) {\r\n\t\t\t\tthis.ItemsFoundSectionHasValue = true;\r\n\r\n\t\t\t\tif (!(((this.ItemsFoundDescription != null) && (this.ItemsFoundDescription != '')) &&\r\n\t\t\t\t\t((this.ItemsFoundAgent != null) && (this.ItemsFoundAgent != '')) &&\r\n\t\t\t\t\t((this.ItemsFoundSignature != null) && (this.ItemsFoundSignature != '')))) {\r\n\t\t\t\t\tthis.IsValid = false;\r\n\t\t\t\t\tthis.ItemsFoundSectionIsValid = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// unaccompanied minors\r\n\t\t\tthis.UMSectionIsValid = true;\r\n\t\t\tthis.UMSectionHasValue = false;\r\n\t\t\tthis.UMNumber = parseInt(this.UMNumber);\r\n\t\t\tif (isNaN(this.UMNumber))\r\n\t\t\t\tthis.UMNumber = 0;\r\n\r\n\t\t\t//UM has a value, if UMNo > 0\r\n\t\t\tif ((this.UMNumber != null) && (this.UMNumber > 0))\r\n\t\t\t\tthis.UMSectionHasValue = true;\r\n\r\n\t\t\t//UM is invalid, if it has a value but not all required fields are in place\r\n\t\t\tif (this.UMSectionHasValue &&\r\n\t\t\t\t(\r\n\t\t\t\t\t(this.UMAgent == null || this.UMAgent == '') ||\r\n\t\t\t\t\t(this.UMSignature == null || this.UMSignature == '')\r\n\t\t\t\t)\r\n\t\t\t) {\r\n\t\t\t\tthis.IsValid = false;\r\n\t\t\t\tthis.UMSectionIsValid = false;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t// luggage \r\n\t\t\tthis.LuggageSectionIsValid = true;\r\n\t\t\tthis.LuggageSectionHasValue = false;\r\n\t\t\tthis.LuggageNumber = parseInt(this.LuggageNumber);\r\n\t\t\tif (isNaN(this.LuggageNumber))\r\n\t\t\t\tthis.LuggageNumber = 0;\r\n\r\n\t\t\t//Luggage has a value, if LuggageNo > 0\r\n\t\t\tif ((this.LuggageNumber != null) && (this.LuggageNumber > 0))\r\n\t\t\t\tthis.LuggageSectionHasValue = true;\r\n\r\n\t\t\tvar today = new Date(this.FlightDate);\r\n\t\t\tthis.WaterSectionIsValid = true;\r\n\t\t\tthis.WaterSectionHasValue = false;\r\n\r\n\t\t\tif (enableWaterUpliftReporting && \r\n\t\t\t\t(((this.WaterUpliftInitial != null) && (this.WaterUpliftInitial != '')) ||\r\n\t\t\t\t((this.WaterUpliftRemarks != null) && (this.WaterUpliftRemarks != '')) || \r\n\t\t\t\t((today.getDate() == 1 || today.getDate() == 15) && waterUpliftSupportingAcTypes.includes(this.AcType)))) {\r\n\t\t\t\tthis.WaterSectionHasValue = true;\r\n\r\n\t\t\t\tif (!((this.WaterUpliftInitial != null) && (this.WaterUpliftInitial != ''))) {\r\n\t\t\t\t\tthis.IsValid = false;\r\n\t\t\t\t\tthis.WaterSectionIsValid = false;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tthis.WaterSectionIsValid = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tthis.GroundServicesSectionHasValue = false;\r\n\t\t\tif (this.ArrivalGroundServices) {\r\n\t\t\t\tfor (var i = 0; i < this.ArrivalGroundServices.length; i++) {\r\n\t\t\t\t\tif (this.ArrivalGroundServices[i].Used) {\r\n\t\t\t\t\t\tthis.GroundServicesSectionHasValue = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (this.DepartureGroundServices) {\r\n\t\t\t\tfor (var i = 0; i < this.DepartureGroundServices.length; i++) {\r\n\t\t\t\t\tif (this.DepartureGroundServices[i].Used) {\r\n\t\t\t\t\t\tthis.GroundServicesSectionHasValue = true;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// bar/trolleys\r\n\t\t\tthis.BarTrolleysIsValid = true;\r\n\t\t\tfor (var i = 0; i < this.BarTrolleys.length; i++) {\r\n\t\t\t\tif (((this.BarTrolleys[i].Position == null) || (this.BarTrolleys[i].Position == '')) && this.BarTrolleys[i].Photos.length == 0) {\r\n\t\t\t\t\tBarTrolleyFactory.deleteFromList(this.BarTrolleys[i],this.BarTrolleys);\r\n\t\t\t\t\t//this.IsValid = false;\r\n\t\t\t\t\t//this.BarTrolleysIsValid = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tshowOrHideBarTrolleyInputs(this);\r\n\r\n\t\t\t// first aid kits\r\n\t\t\tthis.FirstAidKitsIsValid = true;\r\n\t\t\tfor (var i = 0; i < this.FirstAidKits.length; i++) {\r\n\t\t\t\tif ((this.FirstAidKits[i].Position == null) || (this.FirstAidKits[i].Position == '')) {\r\n\t\t\t\t\tthis.IsValid = false;\r\n\t\t\t\t\tthis.FirstAidKitsIsValid = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// medical incidents\r\n\t\t\tthis.MedicalIncidentsIsValid = true;\r\n\t\t\tfor (var i = 0; i < this.MedicalIncidents.length; i++) {\r\n\t\t\t\tif ((this.MedicalIncidents[i].Name == null) || (this.MedicalIncidents[i].Name == '') ||\r\n\t\t\t\t\t(this.MedicalIncidents[i].FAKUsed == null) || (this.MedicalIncidents[i].FAKUsed == '') ||\r\n\t\t\t\t\t(this.MedicalIncidents[i].Symptoms == null) || (this.MedicalIncidents[i].Symptoms == '') ||\r\n\t\t\t\t\t(this.MedicalIncidents[i].DoctorInvolved == null) || (this.MedicalIncidents[i].DoctorInvolved == '')) {\r\n\t\t\t\t\tthis.IsValid = false;\r\n\t\t\t\t\tthis.MedicalIncidentsIsValid = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// special meals issues\r\n\t\t\tthis.SpecialMealIssuesIsValid = true;\r\n\t\t\tfor (var i = 0; i < this.SpecialMealIssues.length; i++) {\r\n\t\t\t\tif ((this.SpecialMealIssues[i].Name == null) || (this.SpecialMealIssues[i].Name == '') ||\r\n\t\t\t\t\t(this.SpecialMealIssues[i].Source == null) || (this.SpecialMealIssues[i].Source == '') ||\r\n\t\t\t\t\t(this.SpecialMealIssues[i].MealType == null) || (this.SpecialMealIssues[i].MealType == '')) {\r\n\t\t\t\t\tthis.IsValid = false;\r\n\t\t\t\t\tthis.SpecialMealIssuesIsValid = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// supplies\r\n\t\t\tthis.SuppliesIsValid = true;\r\n\t\t\tthis.SuppliesErrorMessage = null;\r\n\t\t\tfor (var i = 0; i < this.Supplies.length; i++) {\r\n\t\t\t\tif ((this.Supplies[i].SupplyType == null) || (this.Supplies[i].SupplyType == '') || (this.Supplies[i].SupplyType == '-')) {\r\n\t\t\t\t\tthis.IsValid = false;\r\n\t\t\t\t\tthis.SuppliesIsValid = false;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tfor (var j = 0; j < this.Supplies.length; j++) {\r\n\t\t\t\t\tif ((this.Supplies[i].Id != this.Supplies[j].Id) &&\r\n\t\t\t\t\t\t(this.Supplies[i].SupplyType == this.Supplies[j].SupplyType)) {\r\n\t\t\t\t\t\tthis.IsValid = false;\r\n\t\t\t\t\t\tthis.SuppliesIsValid = false;\r\n\t\t\t\t\t\tthis.SuppliesErrorMessage = \"You cannot have the same supply issue more than once.\";\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// travel value seals\r\n\t\t\tthis.TravelValueSealsIsValid = true;\r\n\t\t\tfor (var i = 0; i < this.TravelValueSeals.length; i++) {\r\n\t\t\t\tif ((this.TravelValueSeals[i].Position == null) || (this.TravelValueSeals[i].Position == '')) {\r\n\t\t\t\t\tthis.IsValid = false;\r\n\t\t\t\t\tthis.TravelValueSealsIsValid = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// travel value incomplete\r\n\t\t\tthis.TravelValueIncompleteIsValid = true;\r\n\t\t\tthis.TravelValueIncompleteErrorMessage = null;\r\n\t\t\tif (this.TravelValueIncomplete) {\r\n\t\t\t\t// \"0\" == \"\" so use === for comparison to empty string\r\n\t\t\t\tif (typeof (this.TravelValueIncompleteRow) == \"undefined\" || this.TravelValueIncompleteRow === \"\" || this.TravelValueIncompleteRow == null) {\r\n\t\t\t\t\tthis.TravelValueIncompleteIsValid = false;\r\n\t\t\t\t\tthis.TravelValueIncompleteErrorMessage = \"Travel Value Stopped at row is required\";\r\n\t\t\t\t} else if (typeof (this.TravelValueIncompleteReason) == \"undefined\" || this.TravelValueIncompleteReason == \"\" || this.TravelValueIncompleteReason == null) {\r\n\t\t\t\t\tthis.TravelValueIncompleteIsValid = false;\r\n\t\t\t\t\tthis.TravelValueIncompleteErrorMessage = \"Travel Value Incomplete Reason is required\";\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\r\n\t\t\t// Incomplete Services \r\n\t\t\tthis.IncompleteServicesIsValid = true;\r\n\t\t\tfor (var i = 0; i < this.IncompleteServices.length; i++) {\r\n\t\t\t\tif ((this.IncompleteServices[i].ServiceClass == null) ||\r\n\t\t\t\t\t(this.IncompleteServices[i].FromRowNo == '') ||\r\n\t\t\t\t\t(this.IncompleteServices[i].ToRowNo == '') ||\r\n\t\t\t\t\t(this.IncompleteServices[i].ServiceType == '') ||\r\n\t\t\t\t\t(this.IncompleteServices[i].Reason == '') ||\r\n\t\t\t\t\t(this.IncompleteServices[i].FromRowNo > this.IncompleteServices[i].ToRowNo)) {\r\n\t\t\t\t\tthis.IsValid = false;\r\n\t\t\t\t\tthis.IncompleteServicesIsValid = false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n /**\r\n * Validate the Crew Positions\r\n * @memberof CabinReportLocalEditFactory\r\n */\r\n\t\tfunction validateCCMS() {\r\n\t\t\tthis.CCMSCrewPositionsErrorMessage = null;\r\n\t\t\tvar valuesInError = new Array();\r\n\t\t\tfor (var i = 0; i < this.CCMSCrewPositions.length; i++) {\r\n\t\t\t\tif ((this.CCMSCrewPositions[i].CCMS == null) || (this.CCMSCrewPositions[i].CCMS == '')) {\r\n\t\t\t\t\tthis.CCMSCrewPositionsErrorMessage = \"You must fill CCMS for all crew members\";\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tvar allCCMSPositions = CCMSFactory.getCCMSFromStorage();\r\n\r\n\t\t\t// if not multiple then this position must not be found in another\r\n\t\t\t// place in the array\r\n\t\t\tvar multiplePositionsInError = new Array();\r\n\t\t\tfor (var i = 0; i < this.CCMSCrewPositions.length; i++) {\r\n\t\t\t\tvar ccmsObj_i = this.getCCMSObj(allCCMSPositions, this.CCMSCrewPositions[i].CCMS);\r\n\t\t\t\tif (ccmsObj_i.ccmsPositionsIsValid) {\r\n\t\t\t\t\tvar ccms_i = ccmsObj_i.ccms;\r\n\t\t\t\t\tif (ccms_i.Multiple == false) {\r\n\t\t\t\t\t\tfor (var j = 0; j < this.CCMSCrewPositions.length; j++) {\r\n\t\t\t\t\t\t\tvar ccmsObj_j = this.getCCMSObj(allCCMSPositions, this.CCMSCrewPositions[j].CCMS);\r\n\t\t\t\t\t\t\tif (ccmsObj_j.ccmsPositionsIsValid) {\r\n\t\t\t\t\t\t\t\tvar ccms_j = ccmsObj_j.ccms;\r\n\t\t\t\t\t\t\t\tif (this.CCMSCrewPositions[i].CrewId != this.CCMSCrewPositions[j].CrewId) {\r\n\r\n\t\t\t\t\t\t\t\t\tif (ccms_i.Position == ccms_j.Position) {\r\n\r\n\t\t\t\t\t\t\t\t\t\tif (multiplePositionsInError.indexOf(ccms_i.Position) < 0)\r\n\t\t\t\t\t\t\t\t\t\t\tmultiplePositionsInError.push(ccms_i.Position);\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tvaluesInError.push(this.CCMSCrewPositions[i].CCMS);\r\n\t\t\t\t\tthis.CCMSCrewPositions[i].CCMS = null;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (valuesInError.length == 1) {\r\n\t\t\t\tthis.CCMSCrewPositionsErrorMessage = \"You cannot assigned the position \" + valuesInError + \" in this flight\";\r\n\t\t\t} else if (valuesInError.length > 1) {\r\n\t\t\t\tthis.CCMSCrewPositionsErrorMessage = \"You cannot assigned the positions \" + valuesInError + \" in this flight\";\r\n\t\t\t}\r\n\r\n\t\t\tif (multiplePositionsInError.length > 0) {\r\n\r\n\t\t\t\tvar multiplePositionError = \"\";\r\n\t\t\t\tfor (var i = 0; i < multiplePositionsInError.length; i++) {\r\n\r\n\t\t\t\t\tif (multiplePositionError != \"\") {\r\n\t\t\t\t\t\tmultiplePositionError = multiplePositionError + \", \";\r\n\t\t\t\t\t}\r\n\t\t\t\t\tmultiplePositionError = multiplePositionError + multiplePositionsInError[i];\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (multiplePositionsInError.length == 1)\r\n\t\t\t\t\tthis.CCMSCrewPositionsErrorMessage = \"You have assigned the position \" + multiplePositionError + \" multiple times\";\r\n\t\t\t\telse\r\n\t\t\t\t\tthis.CCMSCrewPositionsErrorMessage = \"You have assigned the positions \" + multiplePositionError + \" multiple times\";\r\n\t\t\t}\r\n\r\n\t\t\tif (this.CCMSCrewPositionsErrorMessage != null)\r\n\t\t\t\treturn false;\r\n\t\t\telse\r\n\t\t\t\treturn true;\r\n\t\t}\r\n\r\n /**\r\n * Get the CCMS Positions of this aircraft\r\n * @memberof CabinReportLocalEditFactory\r\n */\r\n\t\tfunction getCCMSObj(ccms, pos) {\r\n\t\t\tvar AcTypeIsValid = false;\r\n\t\t\tvar ccmsPositionsIsValid = false;\r\n\t\t\tvar ccmsObj = null;\r\n\t\t\tfor (var i = 0; i < ccms.length; i++) {\r\n\r\n\t\t\t\t// find the positions for this aircraft type\r\n\t\t\t\tif (ccms[i].Aircraft == this.AcType) {\r\n\t\t\t\t\tAcTypeIsValid = true;\r\n\t\t\t\t\tfor (var j = 0; j < ccms[i].Positions.length; j++) {\r\n\t\t\t\t\t\tif (ccms[i].Positions[j].Position == pos) {\r\n\t\t\t\t\t\t\tccmsObj = ccms[i].Positions[j];\r\n\t\t\t\t\t\t\tccmsPositionsIsValid = true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!AcTypeIsValid) {\r\n\t\t\t\tvar log = \"CCMS , POS=\" + this.CCMSCrewPositions[j].CCMS + \", Ac=\" + this.AcType + \", all=\" + JSON.stringify(allCCMSPositions);\r\n\t\t\t\tlog = log.replace(/\"Multiple\":/g, \"\").replace(/\"Position\":/g, \"\").replace(/\"Aircraft\"/g, \"AC\").replace(/true/g, 1).replace(/false/g, 0).replace(/\"/g, \"\").replace(/Positions/g, \"Ps\");\r\n\t\t\t\tLogService.debug(log);\r\n\t\t\t}\r\n\r\n\t\t\treturn {\r\n\t\t\t\tAcTypeIsValid: AcTypeIsValid,\r\n\t\t\t\tccmsPositionsIsValid: ccmsPositionsIsValid,\r\n\t\t\t\tccms: ccmsObj\r\n\t\t\t}\r\n\t\t}\r\n\r\n /**\r\n * Save the Cabin Report\r\n * @memberof CabinReportLocalEditFactory\r\n */\r\n\t\tfunction saveReport() {\r\n\r\n\t\t\t// update the LastUpdated field\r\n\t\t\tthis.LastUpdated = new Date();\r\n\r\n\t\t\t// get the reports array from storage\r\n\t\t\tvar allReports = getCabinReportsFromStorage();\r\n\t\t\tif (allReports == null)\r\n\t\t\t\tallReports = new Array();\r\n\r\n\t\t\t// find the current report from the array (if present)\r\n\t\t\tvar arrayLength = allReports.length;\r\n\t\t\tvar reportIndex = -1;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (allReports[i].ReportGuid == this.ReportGuid) {\r\n\t\t\t\t\treportIndex = i;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// add or update a copy of the current report\r\n\t\t\tif (reportIndex >= 0)\r\n\t\t\t\tallReports[reportIndex] = this;\r\n\t\t\telse\r\n\t\t\t\tallReports.push(this);\r\n\r\n\t\t\t// save\r\n\t\t\tsetCabinReportsToStorage(allReports);\r\n\t\t}\r\n\r\n /**\r\n * Save the Report As Temp\r\n * @memberof CabinReportLocalEditFactory\r\n */\r\n\t\tfunction saveReportAsTemp() {\r\n\r\n\t\t\t// update the LastUpdated field\r\n\t\t\tthis.LastUpdated = new Date();\r\n\r\n\t\t\t// save as temp\r\n\t\t\tlocalStorageMD5Service.remove('cabinReportLocalEdit_TEMP');\r\n\t\t\tlocalStorageMD5Service.set('cabinReportLocalEdit_TEMP', this);\r\n\t\t}\r\n\r\n /**\r\n * Get the remaining characters of this field\r\n * @memberof CabinReportLocalEditFactory\r\n */\r\n\t\tfunction getRemaining(max, text) {\r\n\t\t\tif (typeof (text) === \"undefined\" || text === null) return '';\r\n\t\t\tif (typeof (max) === \"undefined\" || max === null || max < 0 || !max) max = 5000;\r\n\t\t\tvar length = text.length;\r\n\t\t\t/*var matches = text.match(/\\n/g);\r\n\t\t\tif (matches)\r\n\t\t\t\tlength += matches.length;*/\r\n\t\t\t//if(max > length)\r\n\t\t\treturn 'characters left: ' + (max - length);\r\n\t\t\t//else\r\n\t\t\t//\treturn '-full-';\r\n\t\t}\r\n\r\n\t\t//Factory functions\r\n /**\r\n * Extend Object from the default local Cabin Report Object\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {Object} obj a CabinReportLocalEdit\r\n * @returns {Object} CabinReportLocalEdit\r\n */\r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericService.fromObject(obj, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Extend Object List from the default local Cabin Report Object\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {Array} objList a CabinReportLocalEdit list\r\n * @returns {Array} CabinReportLocalEdits\r\n */\r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericService.fromObjectList(objList, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get Cabin Reports from storage\r\n * @memberof CabinReportLocalEditFactory\r\n * @returns {Array} CabinReports\r\n */\r\n\t\tfunction getCabinReportsFromStorage() {\r\n\t\t\treturn GenericService.list(objType, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save Cabin Reports to storage\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {Array} cabinReportLocalEdits A list of Cabin Reports \r\n */\r\n\t\tfunction setCabinReportsToStorage(cabinReportLocalEdits) {\r\n\t\t\tGenericService.saveAll(cabinReportLocalEdits, objType, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Delete Cabin Temporary Report from storage\r\n * @memberof CabinReportLocalEditFactory\r\n */\r\n\t\tfunction deleteTempReport() {\r\n\t\t\tlocalStorageMD5Service.remove('cabinReportLocalEdit_TEMP');\r\n\t\t}\r\n\r\n /**\r\n * Get the CCMS positions of the previous flight\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {string} guid The report GUID\r\n * @param {string} acNo The Aircaft Number\r\n * @param {string} flightDateUTC The flight date in UTC\r\n * @param {string} flightTimeUTC The flight time in UTC\r\n * @return {Array} CCMSpositions\r\n */\r\n\t\tfunction getPreviousCabinReportCcmsPositions(guid, acNo, flightDateUTC, flightTimeUTC) {\r\n\t\t\tvar previousCcms = null;\r\n\t\t\ttry {\r\n\t\t\t\tvar flightDate = new Date(flightDateUTC + ' ' + flightTimeUTC); //date of ref flight\r\n\t\t\t\tvar flightDateMatch = null;\r\n\t\t\t\tvar flightDateCheck = null;\r\n\t\t\t\tvar previousRep = null;\r\n\t\t\t\tvar report = null;\r\n\t\t\t\tvar reports = getCabinReportsFromStorage();\r\n\t\t\t\t//console.debug('Find previous report for ' + acNo + ' ' + flightDateUTC + ' ' + flightTimeUTC);\r\n\t\t\t\tif (reports != null && reports.length > 0) {\r\n\t\t\t\t\t//loop all reports to find the previous one based on the input data\r\n\t\t\t\t\tvar x;\r\n\t\t\t\t\tfor (var i = 0; i < reports.length; i++) {\r\n\t\t\t\t\t\treport = reports[i];\r\n\t\t\t\t\t\tflightDateCheck = new Date(report.ScheduledDepartureDateUTC + \" \" + report.ScheduledDepartureTimeUTC);\r\n\t\t\t\t\t\t//console.debug('\t' + report.AcTailNo + ' ' + report.FlightNo + ' ' + report.Departure + '-' + report.Arrival + ' ' + report.ScheduledDepartureDateUTC + \" \" + report.ScheduledDepartureTimeUTC);\r\n\r\n\t\t\t\t\t\t//flight too old to be \"previous\"\r\n\t\t\t\t\t\tif (((flightDate - flightDateCheck) / 1000 / 60 / 60) > 6) {\r\n\t\t\t\t\t\t\tx = 0;\r\n\t\t\t\t\t\t\t//console.debug('\t\tpast flight, not acceptable');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t//same report as ref one\r\n\t\t\t\t\t\telse if (report.ReportGuid == guid) {\r\n\t\t\t\t\t\t\tx = 1;\r\n\t\t\t\t\t\t\t//console.debug('\t\tsame report');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t//worse match than current one\r\n\t\t\t\t\t\telse if (flightDateMatch != null && flightDateCheck < flightDate && flightDateMatch < flightDateCheck) {\r\n\t\t\t\t\t\t\tx = 2;\r\n\t\t\t\t\t\t\t//console.debug('\t\tprevious match is a closer one');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t//later than ref flight\r\n\t\t\t\t\t\telse if (flightDate < flightDateCheck) {\r\n\t\t\t\t\t\t\tx = 3;\r\n\t\t\t\t\t\t\t//console.debug('\t\tlater than ref flight');\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t//match!\r\n\t\t\t\t\t\telse {\r\n\t\t\t\t\t\t\t//console.debug('\t\tcandidate');\r\n\t\t\t\t\t\t\t//store selected report\r\n\t\t\t\t\t\t\tpreviousRep = report;\r\n\t\t\t\t\t\t\tflightDateMatch = flightDateCheck;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (previousRep != null && previousRep.CCMSCrewPositions != null && previousRep.CCMSCrewPositions.length > 0) {\r\n\t\t\t\t\tpreviousCcms = previousRep.CCMSCrewPositions;\r\n\t\t\t\t}\r\n\t\t\t} catch (e) {\r\n\t\t\t\tconsole.error(e);\r\n\t\t\t}\r\n\t\t\treturn previousCcms;\r\n\t\t}\r\n\r\n /**\r\n * Delete Selected repport\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {string} reportGuid The report's Identifier\r\n */\r\n\t\tfunction deleteReport(reportGuid) {\r\n\t\t\tGenericService.remove(reportGuid, objType, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save Selected Cabin repport\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {Object} report A Cabin Report\r\n */\r\n\t\tfunction setCabinReportToStorage(report) {\r\n\t\t\tGenericService.save(report, objType, objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get Temporary Cabin repport\r\n * @memberof CabinReportLocalEditFactory\r\n * @return {Object} report \r\n */\r\n\t\tfunction getCabinReportLocalEditFromTemp() {\r\n\t\t\tvar cabinReportLocalEdit = localStorageMD5Service.get('cabinReportLocalEdit_TEMP');\r\n\t\t\tcabinReportLocalEdit = checkForNewGroundServices(cabinReportLocalEdit);\r\n\t\t\treturn fromObject(cabinReportLocalEdit);\r\n\t\t}\r\n\r\n /**\r\n * Get the Cabin repport of this flight\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {number} flightId A flight Id\r\n * @return {Object} report \r\n */\r\n\t\tfunction getCabinReportLocalEditForFlight(flightId) {\r\n\t\t\tvar cabinReportLocalEdits = getCabinReportsFromStorage();\r\n\t\t\tif (cabinReportLocalEdits == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\tvar result = null;\r\n\r\n\t\t\tvar arrayLength = cabinReportLocalEdits.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (cabinReportLocalEdits[i].FlightId == flightId) {\r\n\t\t\t\t\tresult = cabinReportLocalEdits[i];\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tresult = checkForNewGroundServices(result);\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\t\t/**\r\n * add any new ground services from storage to the existing report\r\n * @memberof CabinReportLocalEditFactory\r\n\t\t * @param {Object} report\r\n * @return {Object} report \r\n */\r\n\t\tfunction checkForNewGroundServices(report) {\r\n\t\t\tif (report == null)\r\n\t\t\t\treturn report;\r\n\r\n\t\t\tvar depStorageGroundServices = GroundServicesFactory.getGroundServicesByStation(report.Departure);\r\n\t\t\t//var arrStorageGroundServices = GroundServicesFactory.getGroundServicesByStation(report.Arrival);\r\n\t\t\tfor (var i = 0; i < depStorageGroundServices.length; i++) {\r\n\t\t\t\tvar found = false;\r\n\t\t\t\tfor (var j = 0; j < report.DepartureGroundServices.length; j++) {\r\n\t\t\t\t\tif (depStorageGroundServices[i].ServiceType === report.DepartureGroundServices[j].ServiceType) {\r\n\t\t\t\t\t\t//this ground service is available according to the localstorage but its not in the report\r\n\t\t\t\t\t\tfound = true;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\tif (!found) {\r\n\t\t\t\t\treport.DepartureGroundServices.push(depStorageGroundServices[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t//Disable arrival ground services from report:\r\n\t\t\t// for (var i = 0; i < arrStorageGroundServices.length; i++) {\r\n\t\t\t// \tvar found = false;\r\n\t\t\t// \tfor (var j = 0; j < report.ArrivalGroundServices.length; j++){\r\n\t\t\t// \t\tif (arrStorageGroundServices[i].ServiceType === report.ArrivalGroundServices[j].ServiceType){\r\n\t\t\t// \t\t\t//this ground service is available according to the localstorage but its not in the report\r\n\t\t\t// \t\t\tfound = true;\r\n\t\t\t// \t\t\tbreak;\r\n\t\t\t// \t\t}\r\n\t\t\t// \t}\r\n\t\t\t// \tif (!found){\r\n\t\t\t// \t\treport.ArrivalGroundServices.push(arrStorageGroundServices[i]);\r\n\t\t\t// \t}\r\n\t\t\t//}\r\n\t\t\treturn report;\r\n\t\t}\r\n\r\n /**\r\n * Get the Cabin repport\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {string} reportGuid A report Id\r\n * @return {Object} report \r\n */\r\n\t\tfunction getCabinReportLocalEdit(reportGuid) {\r\n\t\t\tvar report = GenericService.get(reportGuid, objType, objCallback);\r\n\t\t\treport = checkForNewGroundServices(report);\r\n\t\t\treturn report;\r\n\t\t}\r\n\r\n /**\r\n * Get the number of reports that need to be synched\r\n * @memberof CabinReportLocalEditFactory\r\n * @return {number} result A Cabin Report\r\n */\r\n\t\tfunction getCabinReportLocalEditCountThatNeedToBeSynched() {\r\n\t\t\tvar cabinReportLocalEdits = getCabinReportsFromStorage();\r\n\t\t\tif (cabinReportLocalEdits == null)\r\n\t\t\t\treturn 0;\r\n\r\n\t\t\tvar result = 0;\r\n\r\n\t\t\tfor (var i = 0; i < cabinReportLocalEdits.length; i++) {\r\n\t\t\t\tif (cabinReportLocalEdits[i].Status === 'completed') {\r\n\t\t\t\t\tresult++;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Cabin report Exist For Route and DutyDate\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {string} Route The flight's route\r\n * @param {string} Dutydate The flight's duty date\r\n * @return {boolean} result\r\n */\r\n\t\tfunction IsExistForRouteDutyDate(Route, Dutydate) {\r\n\t\t\tvar cabinReportLocalEdits = getCabinReportsFromStorage();\r\n\t\t\tif (cabinReportLocalEdits == null)\r\n\t\t\t\treturn false;\r\n\r\n\t\t\tvar result = false;\r\n\r\n\t\t\tfor (var i = 0; i < cabinReportLocalEdits.length; i++) {\r\n\t\t\t\tif (cabinReportLocalEdits[i].Route == Route && cabinReportLocalEdits[i].Dutydate) {\r\n\t\t\t\t\tresult = true;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Get the reports that need to be synched\r\n * @memberof CabinReportLocalEditFactory\r\n * @return {array} result \r\n */\r\n\t\tfunction getCabinReportLocalEditThatNeedToBeSynched() {\r\n\t\t\tvar result = [];\r\n\r\n\t\t\tvar cabinReportLocalEdits = getCabinReportsFromStorage();\r\n\t\t\tif (cabinReportLocalEdits == null)\r\n\t\t\t\treturn result;\r\n\r\n\t\t\tfor (var i = 0; i < cabinReportLocalEdits.length; i++) {\r\n\t\t\t\tif (cabinReportLocalEdits[i].Status === 'completed') {\r\n\t\t\t\t\tresult.push(cabinReportLocalEdits[i]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Gonstructor for a new cabin Report\r\n * @memberof CabinReportLocalEditFactory\r\n * @return {array} result \r\n */\r\n\t\tfunction getNewReport() {\r\n\t\t\treturn GenericService.constructor(objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Mark selected report As Synched\r\n * @memberof CabinReportLocalEditFactory\r\n * @param {string} reportGuid The report Guid\r\n * @return {boolean} isSuccess \r\n */\r\n\t\tfunction markReportAsSynched(reportGuid) {\r\n\r\n\t\t\tvar report = getCabinReportLocalEdit(reportGuid);\r\n\t\t\tif (report == null)\r\n\t\t\t\treturn false;\r\n\r\n\t\t\treport.Status = 'synched';\r\n\t\t\treport.saveReport();\r\n\r\n\t\t\treturn true;\r\n\t\t}\r\n\r\n\t\tfunction showOrHideBarTrolleyInputs(report) {\r\n\t\t\tvar photos = report.BarTrolleys.map(i => i.Photos);\r\n\t\t\tvar photosCount = 0;\r\n\t\t\tif(photos[0]!=undefined){\r\n\t\t\t\tphotosCount = photos[0].length;\r\n\t\t\t}\r\n\t\t\treport.showBarTrolleyUploadImage = photosCount > 0 || report.BarTrolleys.length == 0;\r\n\t\t\treport.showBarTrolleyInsertData = !photosCount > 0 || report.BarTrolleys.length == 0;\r\n\t\t\treport.disableBarTrolleysPhotoRemarks = !photosCount > 0\r\n\t\t}\r\n\t\t\r\n\r\n /**\r\n * Get flight ids with pending reports \r\n * @memberof CabinReportLocalEditFactory\r\n * @return [long] List of flight ids \r\n */\r\n\t\tfunction getFlightIdsWithPendingReports() {\r\n\t\t\tvar cabinReportLocalEdits = getCabinReportsFromStorage();\r\n\t\t\tvar flightIds = [];\r\n\t\t\tif (cabinReportLocalEdits != null)\r\n\t\t\t{\r\n\t\t\t\tvar now = moment();\r\n\t\t\t\t//var now = moment('2016-06-14') //For debug;\r\n\t\t\t\tfor (var i = 0; i < cabinReportLocalEdits.length; i++) {\r\n\t\t\t\t\tvar flightDate = moment(cabinReportLocalEdits[i].FlightDate);\r\n\t\t\t\t\tif (cabinReportLocalEdits[i].Status !== 'stored' && now.diff(flightDate, 'days') < 5) {\r\n\t\t\t\t\t\tflightIds.push(cabinReportLocalEdits[i].FlightId);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn flightIds;\r\n\t\t}\r\n\t\t\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('CabinReportLocalEditCreatorFactory',CabinReportLocalEditCreatorFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportLocalEditCreatorFactory\r\n * @description \r\n * Create a new local Report\r\n * @ngInject\r\n */\r\nfunction CabinReportLocalEditCreatorFactory(FlightFactory, ReportGuidFactory, CabinReportTemplateItemFactory, CabinReportLocalEditFactory, UserFactory, CCMSCrewPositionFactory, GroundServicesFactory) {\r\n\r\n\t\tvar service = {\r\n\t\t\t\tcreateNewLocalReportForFlight : createNewLocalReportForFlight\r\n\t\t}\r\n\t\t\r\n /**\r\n * Create a new Local Report For the Selected Flight\r\n * @memberof CrewAssessmentFactory\r\n * @param {number} flightId \r\n * @returns {object} report \r\n */\r\n\t\tfunction createNewLocalReportForFlight(flightId) {\r\n\r\n\t\t\t// load the user\r\n\t\t\tvar user = UserFactory.getUser();\r\n\t\t\tif (user == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\t// check if a report exists for this flight and user\r\n\t\t\tvar existingReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId);\r\n\t\t\tif (existingReport != null)\r\n\t\t\t\treturn existingReport;\r\n\r\n\t\t\t// get a guid for the report\r\n\t\t\tvar newReportGuid = ReportGuidFactory.getNextGuid();\r\n\t\t\tif (newReportGuid == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\t// load the cabin report template\r\n\t\t\tvar reportTemplateItems = CabinReportTemplateItemFactory.getCabinReportTemplateItemsFromStorage();\r\n\t\t\tif (reportTemplateItems == null)\r\n\t\t\t\treturn null;\r\n\t\t\tif (reportTemplateItems.length == 0)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\t// load the flight\r\n\t\t\tvar flight = FlightFactory.getFlightFromStorage(flightId);\r\n\t\t\tif (flight == null) {\r\n\t\t\t\t// if not found, also check the local flights\r\n\t\t\t\tvar flight = FlightFactory.getLocalFlightFromStorage(flightId);\r\n\r\n\t\t\t\t// if still not found, then return null\r\n\t\t\t\tif (flight == null)\r\n\t\t\t\t\treturn null;\r\n\t\t\t}\r\n\r\n\t\t\t// create the new report\r\n\t\t\tvar newReport = CabinReportLocalEditFactory.getNewReport();\r\n\r\n\t\t\t// assign data on the new report\r\n\t\t\tnewReport.AuthorId = user.id;\r\n\t\t\tnewReport.AuthorAimsId = user.aimsId;\r\n\t\t\tnewReport.AuthorName = user.name;\r\n\t\t\tnewReport.Created = new Date();\r\n\t\t\tnewReport.FlightAimsId = flight.FlightAimsId;\r\n\t\t\tnewReport.FlightId = flight.FlightId;\r\n\t\t\tnewReport.LastUpdated = new Date();\r\n\t\t\tnewReport.AcType = flight.AcType;\r\n\t\t\tnewReport.AcTailNo = flight.AcTailNo;\r\n\t\t\tnewReport.FlightDate = flight.FlightDate;\r\n\t\t\tnewReport.FlightNo = flight.FlightNo;\r\n\t\t\tnewReport.Departure = flight.Departure;\r\n\t\t\tnewReport.Arrival = flight.Arrival;\r\n\t\t\tnewReport.ScheduledDeparture = flight.ScheduledDeparture;\r\n\t\t\tnewReport.ScheduledDepartureDateUTC = flight.ScheduledDepartureDateUTC;\r\n\t\t\tnewReport.ScheduledDepartureTimeUTC = flight.ScheduledDepartureTimeUTC;\r\n\t\t\tnewReport.ReportGuid = newReportGuid;\r\n\t\t\tnewReport.ReportId = null;\r\n\t\t\tnewReport.Status = 'pending';\r\n\t\t\tnewReport.WaterUpliftSuggestedQuantity = flight.WaterUpliftSuggestedQuantity; // TODO\r\n\t\t\tnewReport.VariousIssues = reportTemplateItems;\r\n\t\t\t//details from flight (assuming flight contains these fields)\r\n\t\t\tif (flight.DepartureName) {\r\n\t\t\t\tnewReport.DepartureICAO = flight.DepartureICAO;\r\n\t\t\t\tnewReport.DepartureCountry = flight.DepartureCountry;\r\n\t\t\t\tnewReport.DepartureName = flight.DepartureName;\r\n\t\t\t\tnewReport.ArrivalICAO = flight.ArrivalICAO;\r\n\t\t\t\tnewReport.ArrivalCountry = flight.ArrivalCountry;\r\n\t\t\t\tnewReport.ArrivalName = flight.ArrivalName;\r\n\t\t\t}\r\n\t\t\t//pax figures from flight (assuming flight contains these figures)\r\n\t\t\tif (flight.BookedY >= 0) {\r\n\t\t\t\tnewReport.BookedC = flight.BookedC;\r\n\t\t\t\tnewReport.BookedY = flight.BookedY;\r\n\t\t\t\tnewReport.BookedInf = flight.BookedInf;\r\n\t\t\t\tnewReport.BookedPad = flight.BookedPad;\r\n\t\t\t\tnewReport.BookedChld = flight.BookedChld;\r\n\t\t\t\tnewReport.ActualC = flight.ActualC;\r\n\t\t\t\tnewReport.ActualY = flight.ActualY;\r\n\t\t\t\tnewReport.ActualInf = flight.ActualInf;\r\n\t\t\t\tnewReport.ActualPad = flight.ActualPad;\r\n\t\t\t\tnewReport.ActualChld = flight.ActualChld;\r\n\t\t\t}\r\n\r\n\t\t\t// fix the CCMS positions\r\n\t\t\tfor (var i = 0; i < flight.crew.length; i++) {\r\n\r\n\t\t\t\tif ((flight.crew[i].isDHC == false) &&\r\n\t\t\t\t\t(flight.crew[i].position != 'CP') &&\r\n\t\t\t\t\t(flight.crew[i].position != 'FO')) {\r\n\t\t\t\t\tvar crewPosition = CCMSCrewPositionFactory.createNew();\r\n\t\t\t\t\tcrewPosition.CrewId = flight.crew[i].aimsId;\r\n\t\t\t\t\tcrewPosition.Initials = flight.crew[i].shortname;\r\n\t\t\t\t\tcrewPosition.Name = flight.crew[i].name;\r\n\t\t\t\t\tcrewPosition.Position = flight.crew[i].position;\r\n\t\t\t\t\tcrewPosition.IsManual = false;\r\n\t\t\t\t\tcrewPosition.CrewComments = null;\r\n\t\t\t\t\tcrewPosition.HasCrewComments = false;\r\n\t\t\t\t\tcrewPosition.needsAdditionalFeedback = false;\r\n\t\t\t\t\tnewReport.CCMSCrewPositions.push(crewPosition);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tnewReport.crew = flight.crew;\r\n\r\n\t\t\t//new values\r\n\t\t\tnewReport.DepartureTimezone = flight.DepartureTimezone;\r\n\t\t\tnewReport.ArrivalTimezone = flight.ArrivalTimezone;\r\n\t\t\tnewReport.CallSign = flight.CallSign;\r\n\t\t\tnewReport.ScheduledArrival = flight.ScheduledArrival;\r\n\t\t\tnewReport.DepartureGate = flight.DepartureGate;\r\n\t\t\tnewReport.Route = flight.Route;\r\n\t\t\tnewReport.DutyDate = flight.DutyDate;\r\n\r\n\t\t\t//add ground services\r\n\t\t\tnewReport.DepartureGroundServices = GroundServicesFactory.getGroundServicesByStation(flight.Departure);\r\n\t\t\t//We don't show arrival services any more... \r\n\t\t\t//newReport.ArrivalGroundServices = GroundServicesFactory.getGroundServicesByStation(flight.Arrival);\r\n\r\n\t\t\tnewReport.GroomingReports = [];\r\n\r\n\t\t\tnewReport.updateTotals();\r\n\r\n\t\t\t// return the new report\r\n\t\t\treturn newReport;\r\n\t\t}\r\n\r\n\t\treturn service;\r\n}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('CabinReportRestoreFactory',CabinReportRestoreFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportRestoreFactory\r\n * @description \r\n * Manage Local Cabin Reports.\r\n * @ngInject\r\n */\r\n function CabinReportRestoreFactory(localStorageMD5Service, FlightFactory, CabinReportLocalEditFactory,IndexedDBService) {\r\n\r\n var IdxType = 'Reports';\r\n\r\n \r\n var service = {\r\n getReportsFromIdx : getReportsFromIdx,\r\n setReportsToIdx : setReportsToIdx,\r\n updateReportToIdx : updateReportToIdx,\r\n addReportToIdx : addReportToIdx,\r\n deleteReportFromIdx : deleteReportFromIdx,\r\n clearReportsFromIdx :clearReportsFromIdx,\r\n getReportsFromLs : getReportsFromLs,\r\n backUpReports : backUpReports,\r\n restoreReports : restoreReports\r\n }\r\n\r\n /**\r\n * Get Reports\r\n * @memberof CabinReportRestoreFactory\r\n * @param {function} callback \r\n */\r\n function getReportsFromIdx(callback) {\r\n //return GenericService.list(Idx,objCallback);\r\n IndexedDBService.getAll(IdxType).then(function (results) {\r\n callback(results);\r\n });\r\n };\r\n\r\n /**\r\n * Set Reports\r\n * @memberof CabinReportRestoreFactory\r\n * @param {array} Reports a list of Reports to set to indexedDB\r\n */\r\n function setReportsToIdx(Reports) {\r\n IndexedDBService.addAll(IdxType, Reports);\r\n };\r\n\r\n /**\r\n * Update Report to Storage\r\n * @memberof CabinReportRestoreFactory\r\n * @param {object} Report a Report\r\n */\r\n function updateReportToIdx(Report) {\r\n IndexedDBService.put(IdxType, Report);\r\n };\r\n\r\n function info(){\r\n IndexedDBService.info(IdxType);\r\n }\r\n\r\n /**\r\n * Add Report to Storage\r\n * @memberof CabinReportRestoreFactory\r\n * @param {object} Report a Report\r\n */\r\n function addReportToIdx(Report) {\r\n IndexedDBService.add(IdxType, Report);\r\n };\r\n\r\n /**\r\n * Delete Report from Storage\r\n * @memberof CabinReportRestoreFactory\r\n * @param {number} RerportGuid The unique Identifier of the Report\r\n */\r\n function deleteReportFromIdx(ReportId) {\r\n IndexedDBService.remove(IdxType, ReportId);\r\n };\r\n\r\n /**\r\n * Clear Report from Storage\r\n * @memberof CabinReportRestoreFactory\r\n */\r\n function clearReportsFromIdx() {\r\n IndexedDBService.removeAll(IdxType);\r\n };\r\n\r\n\r\n /**\r\n * Get Cabin Reports from storage\r\n * @memberof CabinReportLocalEditFactory\r\n * @returns {Array} CabinReports\r\n */\r\n\t\tfunction getReportsFromLs() { \r\n\t\t\treturn localStorageMD5Service.get('cabinReportLocalEdits');\r\n\t\t}\r\n\r\n /**\r\n * Get reports from IndexedDB and delete the reports that have been stored\r\n * @memberof CabinReportRestoreFactory\r\n */\r\n function getReportsFromIdxDeleteStoredReports(callback){\r\n var reportsIdx = [];\r\n var storedReportsLs = FlightFactory.getFlightsWithStoredReport();\r\n getReportsFromIdx(function (results){\r\n for(var i=0; i0){\r\n for(var i=0; i< reportsAll.length; i++){\r\n var reportLs = reportsAll[i];\r\n var isExisting = reportsIdx.some(function (item) {\r\n return reportLs.FlightId == item.FlightId;\r\n });\r\n if(isExisting){\r\n //Replace the report\r\n deleteReportFromIdx(reportLs.FlightId);\r\n addReportToIdx(reportLs);\r\n }\r\n else{\r\n //Insert the report\r\n addReportToIdx(reportLs);\r\n }\r\n }\r\n }\r\n\r\n });\r\n\r\n\t\t}\r\n\r\n /**\r\n * Restore reports. Compares the reports from localstorage and from IndexedDB, and it inserts the reports that are missing from local storage. \r\n * Steps:\r\n * 1.\r\n * @memberof CabinReportRestoreFactory\r\n * @returns {array} list of flightNo foreach restored report \r\n */\r\n\t\tfunction restoreReports(callback) {\r\n\t\t\tgetReportsFromIdxDeleteStoredReports(function (reportsIdx){\r\n var results = [];\r\n var reportsAll = [];\r\n reportsAll = getReportsFromLs();\r\n for(var i=0; i< reportsIdx.length; i++){\r\n //Check if exists\r\n var isExisting = reportsAll.some(function (item) {\r\n return reportsIdx[i].FlightId == item.FlightId \r\n && (reportsIdx[i].Status == \"draft\" || reportsIdx[i].Status == \"completed\");\r\n });\r\n if(isExisting){\r\n //Delete existing reports\r\n deleteReportFromIdx(reportsIdx[i].FlightId);\r\n }\r\n else{\r\n //Insert reports that are not existed\r\n var extendReport = CabinReportLocalEditFactory.fromObject(reportsIdx[i]);\r\n extendReport.Status = \"draft\";\r\n extendReport.saveReport();\r\n FlightFactory.updateFlightFromReport(extendReport);\r\n\r\n //Then delete from indexed db\r\n deleteReportFromIdx(reportsIdx[i].FlightId);\r\n results.push(reportsIdx[i].FlightNo );\r\n }\r\n }\r\n callback(results);\r\n });\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('CabinReportSendToServerFactory', CabinReportSendToServerFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportSendToServerFactory\r\n * @description \r\n * Transform Cabin Reports in order to send them to the server\r\n * @ngInject\r\n */\r\nfunction CabinReportSendToServerFactory() {\r\n\r\n /**\r\n * Initialize the CabinReportSendToServer\r\n * @memberof CabinReportSendToServerFactory\r\n */\r\n\t\tfunction CabinReportSendToServer() {\r\n\t\t\tthis.Created = null;\r\n\t\t\tthis.LastUpdated = null;\r\n\t\t\tthis.FlightAimsId = null;\r\n\t\t\tthis.FlightId = null;\r\n\t\t\tthis.FlightDate = null;\r\n\t\t\tthis.FlightNo = null;\r\n\t\t\tthis.Departure = null;\r\n\t\t\tthis.Arrival = null;\r\n\t\t\tthis.ReportGuid = null;\r\n\t\t\tthis.AuthorCrewId = null;\r\n\t\t\tthis.AuthorCrewAimsId = null;\r\n\r\n\t\t\tthis.ActualPassengerC = \"\";\r\n\t\t\tthis.ActualPassengerY = \"\";\r\n\r\n\t\t\tthis.CCMSCrewPositions = [];\r\n\t\t\tthis.CrewRemarks = null;\r\n \r\n\t\t\tthis.ItemsFoundDescription = null;\r\n\t\t\tthis.ItemsFoundAgent = null;\r\n\t\t\tthis.ItemsFoundSignature = null;\r\n\t\t\tthis.UMNumber = 0;\r\n\t\t\tthis.UMDescription = null;\r\n\t\t\tthis.UMAgent = null;\r\n\t\t\tthis.UMSignature = null;\r\n\t\t\tthis.WaterUpliftSuggestedQuantity = null;\r\n\t\t\tthis.WaterUpliftInitial = null;\r\n\t\t\tthis.WaterUpliftRemarks = null;\r\n\t\t\tthis.BarTrolleys = [];\r\n\t\t\tthis.FirstAidKits = [];\r\n\t\t\tthis.MedicalIncidents = [];\r\n\t\t\tthis.SpecialMealIssues = [];\r\n\t\t\tthis.Supplies = [];\r\n\t\t\tthis.TravelValueSeals = [];\r\n\t\t\tthis.LuggageNumber = 0;\r\n\t\t\tthis.LuggageDescription = null;\r\n\r\n\t\t\tthis.TravelValueIncomplete = false;\r\n\t\t\tthis.TravelValueIncompleteRow = null;\r\n\t\t\tthis.TravelValueIncompleteReason = null;\r\n\t\t\tthis.TravelValueRemarks = null;\r\n\t\t\tthis.Remarks = null;\r\n\t\t\tthis.VariousIssues = [];\r\n\t\t\tthis.DepartureGroundServices = [];\r\n\t\t\tthis.ArrivalGroundServices = [];\r\n\t\t\tthis.UpgradedPassengers = [];\r\n\t\t\tthis.ChangedSeats = [];\r\n\t\t\t//BoardingTimes\r\n\t\t\tthis.BoardingTimesRemarks = null;\r\n\t\t\tthis.FirstPaxTime = null;\r\n\t\t\tthis.LastPaxTime = null;\r\n\r\n\t\t\tthis.GroomingReports = [];\r\n\t\t}\r\n \r\n /**\r\n * Initialize the CabinReportSendToServerItem\r\n * @memberof CabinReportSendToServerFactory\r\n */\r\n function CabinReportSendToServerItem() {\r\n\t\t\tthis.ReportGuid = null;\r\n\t\t\tthis.TemplateItemId = null;\r\n\t\t\tthis.Value = 0;\r\n\t\t\tthis.Remarks = '';\r\n\t\t\tthis.Photos = new Array();\r\n\t\t}\r\n\t\t\t\r\n\t\tvar service = {\r\n\t\t\tgetCompletedListFromCabinReportLocalEdits : getCompletedListFromCabinReportLocalEdits,\r\n\t\t\tgetReportFromCabinReportLocalEdit : getReportFromCabinReportLocalEdit,\r\n\t\t\tstripIds : stripIds\r\n\t\t}\r\n\r\n /**\r\n * Transform all cabin local reports in order to be sent to the server\r\n * @memberof CabinReportSendToServerFactory\r\n * @param {Array} cabinReportLocalEdits\r\n * @returns {Array} CabinReportSendToServer \r\n */\r\n\t\tfunction getCompletedListFromCabinReportLocalEdits(cabinReportLocalEdits) {\r\n\t\t\tvar result = [];\r\n\r\n\t\t\tif (cabinReportLocalEdits == null)\r\n\t\t\t\treturn result;\r\n\r\n\t\t\tvar arrayLength = cabinReportLocalEdits.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (cabinReportLocalEdits[i].Status === 'completed') {\r\n\t\t\t\t\tresult.push(getReportFromCabinReportLocalEdit(cabinReportLocalEdits[i]));\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t//Temporary: fix: Ground Services: Used values (true/false) from local storage.\r\n\t\t \tvar resultChecked = fixUsedValueLS(result);\r\n\r\n\t\t\treturn resultChecked;\r\n\t\t}\r\n\r\n\t\t//Temporary: fix - Ground Services - local storage from true/false values. (int Used: 0:false, 1:true, 2:inop) \r\n\t\tfunction fixUsedValueLS(cabinReportLocalEdits){\r\n\t\t\tfor (var i = 0; i < cabinReportLocalEdits.length; i++) {\r\n\t\t\t\tif(cabinReportLocalEdits[i].DepartureGroundServices.length > 0){\r\n\t\t\t\t\tfor(var j = 0; j < cabinReportLocalEdits[i].DepartureGroundServices.length; j++){\r\n\t\t\t\t\t\tif (cabinReportLocalEdits[i].DepartureGroundServices[j]){\r\n\t\t\t\t\t\t\tif (cabinReportLocalEdits[i].DepartureGroundServices[j].Used === true) {\r\n\t\t\t\t\t\t\t\tcabinReportLocalEdits[i].DepartureGroundServices[j].Used = 1;\r\n\t\t\t\t\t\t\t}else if (cabinReportLocalEdits[i].DepartureGroundServices[j].Used === false){\r\n\t\t\t\t\t\t\t\tcabinReportLocalEdits[i].DepartureGroundServices[j].Used = 0;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn cabinReportLocalEdits;\r\n\t\t}\r\n\r\n\r\n /**\r\n * Transform a cabin local reports in order to be sent to the server\r\n * @memberof CabinReportSendToServerFactory\r\n * @param {object} cabinReportLocalEdit\r\n * @returns {object} CabinReportSendToServer \r\n */\r\n\t\tfunction getReportFromCabinReportLocalEdit(cabinReportLocalEdit) {\r\n\t\t\tvar result = new CabinReportSendToServer();\r\n\r\n\t\t\tresult.Created = cabinReportLocalEdit.Created;\r\n\t\t\tresult.LastUpdated = cabinReportLocalEdit.LastUpdated;\r\n\t\t\tresult.FlightAimsId = cabinReportLocalEdit.FlightAimsId;\r\n\t\t\tresult.FlightId = cabinReportLocalEdit.FlightId;\r\n\t\t\tresult.FlightDate = cabinReportLocalEdit.FlightDate;\r\n\t\t\tresult.FlightNo = cabinReportLocalEdit.FlightNo;\r\n\t\t\tresult.Departure = cabinReportLocalEdit.Departure;\r\n\t\t\tresult.Arrival = cabinReportLocalEdit.Arrival;\r\n\t\t\tresult.ReportGuid = cabinReportLocalEdit.ReportGuid;\r\n\t\t\tresult.AuthorCrewId = cabinReportLocalEdit.AuthorId;\r\n\t\t\tresult.AuthorCrewAimsId = cabinReportLocalEdit.AuthorAimsId;\r\n\r\n\t\t\tresult.ActualPassengerC = cabinReportLocalEdit.ActualPassengerC;\r\n\t\t\tresult.ActualPassengerY = cabinReportLocalEdit.ActualPassengerY;\r\n\r\n\t\t\tresult.CrewRemarks = cabinReportLocalEdit.CrewRemarks;\r\n\r\n\t\t\tresult.ItemsFoundDescription = cabinReportLocalEdit.ItemsFoundDescription;\r\n\t\t\tresult.ItemsFoundAgent = cabinReportLocalEdit.ItemsFoundAgent;\r\n\t\t\tresult.ItemsFoundSignature = cabinReportLocalEdit.ItemsFoundSignature;\r\n\r\n\t\t\tresult.UMNumber = cabinReportLocalEdit.UMNumber;\r\n\t\t\tresult.UMDescription = cabinReportLocalEdit.UMDescription;\r\n\t\t\tresult.UMAgent = cabinReportLocalEdit.UMAgent;\r\n\t\t\tresult.UMSignature = cabinReportLocalEdit.UMSignature;\r\n\r\n\t\t\tresult.LuggageNumber = cabinReportLocalEdit.LuggageNumber;\r\n\t\t\tresult.LuggageDescription = cabinReportLocalEdit.LuggageDescription;\r\n\r\n\t\t\tresult.WaterUpliftSuggestedQuantity = cabinReportLocalEdit.WaterUpliftSuggestedQuantity;\r\n\t\t\tresult.WaterUpliftInitial = cabinReportLocalEdit.WaterUpliftInitial;\r\n\t\t\tresult.WaterUpliftRemarks = cabinReportLocalEdit.WaterUpliftRemarks;\r\n\r\n\t\t\tresult.CCMSCrewPositions = stripIds(cabinReportLocalEdit.CCMSCrewPositions);\r\n\t\t\tresult.BarTrolleys = stripIds(cabinReportLocalEdit.BarTrolleys);\r\n\t\t\tresult.FirstAidKits = stripIds(cabinReportLocalEdit.FirstAidKits);\r\n\t\t\tresult.MedicalIncidents = stripIds(cabinReportLocalEdit.MedicalIncidents);\r\n\t\t\tresult.SpecialMealIssues = stripIds(cabinReportLocalEdit.SpecialMealIssues);\r\n\t\t\tresult.Supplies = stripIds(cabinReportLocalEdit.Supplies);\r\n\t\t\tresult.TravelValueSeals = stripIds(cabinReportLocalEdit.TravelValueSeals);\r\n\r\n\t\t\tresult.TravelValueIncomplete = cabinReportLocalEdit.TravelValueIncomplete;\r\n\t\t\tresult.TravelValueIncompleteRow = cabinReportLocalEdit.TravelValueIncompleteRow;\r\n\t\t\tresult.TravelValueIncompleteReason = cabinReportLocalEdit.TravelValueIncompleteReason;\r\n\t\t\tresult.TravelValueRemarks = cabinReportLocalEdit.TravelValueRemarks;\r\n\t\t\tresult.Remarks = cabinReportLocalEdit.Remarks;\r\n\t\t\tresult.ArrivalGroundServices = cabinReportLocalEdit.ArrivalGroundServices;\r\n\t\t\tresult.DepartureGroundServices = cabinReportLocalEdit.DepartureGroundServices;\r\n\t\t\tresult.UpgradedPassengers = cabinReportLocalEdit.UpgradedPassengers;\r\n\t\t\tresult.ChangedSeats = cabinReportLocalEdit.ChangedSeats;\r\n\t\t\tresult.IncompleteServices = cabinReportLocalEdit.IncompleteServices;\r\n\t\t\tresult.BoardingTimesRemarks = cabinReportLocalEdit.BoardingTimesRemarks;\r\n\t\t\tresult.DisembarkationTimeRemarks = cabinReportLocalEdit.DisembarkationTimesRemarks;\r\n\t\t\t\r\n\t\t\tif(cabinReportLocalEdit.FirstPaxTime){\r\n\t\t\t\tresult.FirstPaxTime = cabinReportLocalEdit.FirstPaxTime;\r\n\t\t\t}\r\n\t\t\tif(cabinReportLocalEdit.LastPaxTime){\r\n\t\t\t\tresult.LastPaxTime = cabinReportLocalEdit.LastPaxTime;\r\n\t\t\t}\r\n\t\t\tif(cabinReportLocalEdit.FirstPaxDisembarkationTime){\r\n\t\t\t\tresult.FirstPaxDisembarkationTime = cabinReportLocalEdit.FirstPaxDisembarkationTime;\r\n\t\t\t}\r\n\t\t\tif(cabinReportLocalEdit.LastPaxDisembarkationTime){\r\n\t\t\t\tresult.LastPaxDisembarkationTime = cabinReportLocalEdit.LastPaxDisembarkationTime;\r\n\t\t\t}\r\n\r\n\t\t\tresult.VariousIssues = [];\r\n\r\n\t\t\tvar itemCount = cabinReportLocalEdit.VariousIssues.length;\r\n\t\t\tfor (var i = 0; i < itemCount; i++) {\r\n\r\n\t\t\t\tvar newItem = new CabinReportSendToServerItem();\r\n\t\t\t\tnewItem.ReportGuid = cabinReportLocalEdit.ReportGuid;\r\n\t\t\t\tnewItem.TemplateItemId = cabinReportLocalEdit.VariousIssues[i].Id;\r\n\t\t\t\tnewItem.Value = cabinReportLocalEdit.VariousIssues[i].ItemHasValue ? 1 : 0;\r\n\t\t\t\tif (newItem.Value == 1) {\r\n\t\t\t\t\tnewItem.Remarks = cabinReportLocalEdit.VariousIssues[i].ItemValue;\r\n\t\t\t\t\tnewItem.Photos = stripIds(cabinReportLocalEdit.VariousIssues[i].Photos);\r\n\t\t\t\t}\r\n\t\t\t\tresult.VariousIssues.push(newItem);\r\n\r\n\t\t\t}\r\n\r\n\t\t\tresult.GroomingReports = cabinReportLocalEdit.GroomingReports;\r\n\t\t\t\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Strip Ids of selected input\r\n * @memberof CabinReportSendToServerFactory\r\n * @param {array} inputArray\r\n * @returns {object} stripedInputArray \r\n */\r\n\t\tfunction stripIds(inputArray) {\r\n\t\t\tfor (var i = 0; i < inputArray.length; i++) {\r\n\t\t\t\tdelete inputArray[i].Id;\r\n\t\t\t}\r\n\t\t\treturn inputArray;\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('CabinReportSyncResultFactory', CabinReportSyncResultFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportSyncResultFactory\r\n * @description \r\n * Manage Cabin Report Sync Results\r\n * @ngInject\r\n */\r\nfunction CabinReportSyncResultFactory(GenericService) {\r\n\r\n /**\r\n * Initialize the CabinReportSyncResult\r\n * @memberof CabinReportSyncResultFactory\r\n */\r\n\t\tfunction CabinReportSyncResult() {\r\n\t\t\tthis.reportGuid = null;\r\n\t\t\tthis.message = null;\r\n\t\t\tthis.success = null;\r\n\t\t\tthis.FlightAimsId = null;\r\n\t\t\tthis.FlightId = null;\r\n\t\t\tthis.ScheduledDepartureDateUTC = null;\r\n\t\t\tthis.FlightNo = null;\r\n\t\t\tthis.Departure = null;\r\n\t\t\tthis.Arrival = null;\r\n\t\t\tthis.ScheduledDepartureTimeUTC = null;\r\n\t\t\tthis.AcTailNo = null;\r\n\t\t\tthis.Result = null;\r\n\t\t\tthis.getRoute = getRoute;\r\n\t\t}\r\n\r\n /**\r\n * Get Report Route\r\n * @memberof CabinReportSyncResultFactory\r\n * @return {string} route\r\n */\r\n\t\tfunction getRoute() {\r\n\t\t\tif (this.Departure == null && this.Arrival == null) return '-null-';\r\n\t\t\telse return (this.Departure || '?') + '-' + (this.Arrival || '?');\r\n\t\t}\r\n\t\t\t\t\r\n\t\tvar objType = 'cabinReportSyncResults';\r\n\t\tvar objCallback = CabinReportSyncResult; \r\n\t\t\r\n\t\tvar service = {\r\n\t\t\tgetSyncResult : getSyncResult,\r\n\t\t\tgetCabinReportSyncResultsFromStorage : getCabinReportSyncResultsFromStorage,\r\n\t\t\tsetCabinReportSyncResultsToStorage : setCabinReportSyncResultsToStorage,\r\n\t\t\tgetSuccesses : getSuccesses,\r\n\t\t\tgetFailures : getFailures,\r\n\t\t\tfromObjectList : fromObjectList\r\n\t\t}\r\n \r\n /**\r\n * Extend an array of Objects from the default CabinReportSyncResult Object\r\n * @memberof CabinReportSyncResultFactory\r\n * @param {Array} objList an Array Of Cabin Report Sync Results\r\n * @returns {Array} CabinReportSyncResults\r\n */\r\n\t\tfunction fromObjectList (objList){\r\n\t\t\treturn GenericService.fromObjectList(objList,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get Sync Result from given list\r\n * @memberof CabinReportSyncResultFactory\r\n * @param {Array} syncResults an Array Of Cabin Report Sync Results\r\n * @param {string} reportGuid The report's Guid\r\n * @returns {object} CabinReportSyncResult\r\n */\r\n\t\tfunction getSyncResult(syncResults, reportGuid) {\r\n\t\t\tif (syncResults == null)\r\n\t\t\t\treturn null;\r\n\r\n\t\t\tvar result = null;\r\n\t\t\tvar arrayLength = syncResults.length;\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tif (syncResults[i].reportGuid == reportGuid) {\r\n\t\t\t\t\tresult = syncResults[i];\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t};\r\n\r\n /**\r\n * Get Sync Results\r\n * @memberof CabinReportSyncResultFactory\r\n * @returns {array} CabinReportSyncResults\r\n */\r\n\t\tfunction getCabinReportSyncResultsFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Set Sync Results\r\n * @memberof CabinReportSyncResultFactory\r\n * @param {Array} syncResults an Array Of Cabin Report Sync Results\r\n */\r\n\t\tfunction setCabinReportSyncResultsToStorage(cabinReportSyncResults) {\r\n\t\t\tGenericService.saveAll(cabinReportSyncResults,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Get Successfull Sync Results from given syncResult\r\n * @memberof CabinReportSyncResultFactory\r\n * @returns {array} successes\r\n */\r\n\t\tfunction getSuccesses(syncResults) {\r\n\t\t\tvar result = 0;\r\n\r\n\t\t\tfor (var i = 0; i < syncResults.length; i++) {\r\n\t\t\t\tif (syncResults[i].success == true) {\r\n\t\t\t\t\tresult = result + 1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n /**\r\n * Get Failed Sync Results from given syncResults\r\n * @memberof CabinReportSyncResultFactory\r\n * @returns {array} failures\r\n */\r\n\t\tfunction getFailures(syncResults) {\r\n\t\t\tvar result = 0;\r\n\t\t\tfor (var i = 0; i < syncResults.length; i++) {\r\n\t\t\t\tif (syncResults[i].success == false) {\r\n\t\t\t\t\tresult = result + 1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('CabinReportTemplateItemFactory', CabinReportTemplateItemFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CabinReportTemplateItemFactory\r\n * @description \r\n * Manage Cabin Report Template Item.\r\n * @ngInject\r\n */\r\nfunction CabinReportTemplateItemFactory(GenericService) {\r\n\r\n /**\r\n * Initialize the CabinReportTemplateItem\r\n * @memberof CabinReportTemplateItemFactory\r\n */\r\n\t\tfunction CabinReportTemplateItem() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.Hint = null;\r\n\t\t\tthis.Label = null;\r\n\t\t\tthis.OrderNo = null;\r\n\t\t\tthis.CategoryLabel = null;\r\n\t\t\tthis.PresetComments = null;\r\n\t\t\tthis.Photos = new Array();\r\n\t\t\tthis.GetId = GetId;\r\n\t\t}\r\n\r\n\t\tvar objType = 'cabinReportTemplateItems';\r\n\t\tvar objCallback = CabinReportTemplateItem;\r\n\r\n\t\tvar service = \r\n\t\t{ \r\n\t\t\tgetCabinReportTemplateItemsFromStorage : getCabinReportTemplateItemsFromStorage,\r\n\t\t\tsetCabinReportTemplateItemsToStorage : setCabinReportTemplateItemsToStorage,\r\n\t\t\tnewItem : newItem\r\n\t\t};\r\n\t\t\t\r\n /**\r\n * Overide default get Id\r\n * @memberof CabinReportTemplateItemFactory\r\n * @returns {number} Id \r\n */\r\n\t\tfunction GetId(){\r\n\t\t\treturn this.Id;\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Get Cabin Report Template Items\r\n * @memberof CabinReportTemplateItemFactory\r\n * @returns {Array} CabinReportTemplateItems \r\n */\r\n\t\tfunction getCabinReportTemplateItemsFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Save Cabin Report Template Items to storage\r\n * @memberof CabinReportTemplateItemFactory\r\n * @param {Array} CabinReportTemplateItems A list of Cabin Report Template Items\r\n */\r\n\t\tfunction setCabinReportTemplateItemsToStorage(cabinReportTemplateItems) {\r\n\t\t\tGenericService.saveAll(cabinReportTemplateItems,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Create a new Cabin Report Template Item \r\n * @memberof CabinReportTemplateItemFactory\r\n * @return {object} CabinReportTemplateItem\r\n */\r\n\t\tfunction newItem() {\r\n\t\t\treturn GenericService.constructor(objCallback);\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.controller('ReportCtrl', ReportCtrl);\r\n\t/**\r\n\t* @memberof CabinReports\r\n\t* @ngdoc controller\r\n\t* @name ReportCtrl\r\n\t* @description \r\n\t* Manages the Report View\r\n\t* @ngInject\r\n\t*/\r\n\tfunction ReportCtrl($scope, $log, $uibModal, $timeout, $routeParams, UserFactory, FlightFactory,\r\n\t\tCabinReportLocalEditFactory, CabinReportLocalEditCreatorFactory, $location, SettingsMain,\r\n\t\tWaterUpliftActionFactory, enableWaterUpliftReporting, BarTrolleyFactory, FirstAidKitFactory, MedicalIncidentFactory,\r\n\t\tSpecialMealIssueFactory, IncompleteServicesIssueFactory, SupplyFactory, TravelValueSealFactory,\r\n\t\tCCMSCrewPositionFactory, CCMSFactory, ReportGuidFactory, TravelValueIncompleteReasonFactory, LogService,\r\n\t\tCrewAssessmentFactory, $route, InfoAPIService, customerIncidentQuestionIds, PaxInfoFactory, GroomingCategoriesFactory) {\r\n\r\n\t\t// get the report id\r\n\t\tvar reportId = $routeParams.reportId;\r\n\t\tvar report = null;\r\n\t\tvar user = UserFactory.getUser();\r\n\t\tvar editingPage = SettingsMain.getEditingPage();\r\n\r\n\t\t$scope.IsCustomerIncident = IsCustomerIncident;\r\n\t\t$scope.enableWaterUpliftReporting = enableWaterUpliftReporting;\r\n\r\n\t\tfunction IsCustomerIncident(id) {\r\n\t\t\treturn customerIncidentQuestionIds.includes(id);\r\n\t\t}\r\n\r\n\t\tvar groomingCategories = GroomingCategoriesFactory.getGroomingCategories();\r\n\t\t$scope.hasGroomingCategories = groomingCategories.length > 0;\r\n\t\t\r\n\t\t$scope.discard = function () {\r\n\t\t\tif (report == null) {\r\n\t\t\t\treport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId);\r\n\t\t\t}\r\n\t\t\tvar guid = report.ReportGuid;\r\n\t\t\tvar status = report.Status;\r\n\r\n\t\t\t// delete the temp report\r\n\t\t\tCabinReportLocalEditFactory.deleteTempReport();\r\n\r\n\t\t\t//reuse guid if this was a new report\r\n\t\t\tif (status == 'pending')\r\n\t\t\t\tReportGuidFactory.restoreGuid(report.ReportGuid);\r\n\r\n\t\t\t// new / edit existing / load from temp\r\n\t\t\tif (reportId.startsWith('new:')) {\r\n\t\t\t\tvar flightId = $routeParams.flightId;\r\n\t\t\t\t// create a new report\r\n\t\t\t\tvar newLocalReport = CabinReportLocalEditCreatorFactory.createNewLocalReportForFlight(flightId);\r\n\r\n\t\t\t\tif (newLocalReport == null) {\r\n\t\t\t\t\tbootbox.alert(\"

Attention

Unable to create a new log!
Available pool of resources has been depleted and you need to synchronize with the server to renew it.\",\r\n\t\t\t\t\t\tfunction () {\r\n\t\t\t\t\t\t\t$location.path(\"/\");\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// load the new report\r\n\t\t\t\t\treport = newLocalReport;\r\n\t\t\t\t}\r\n\t\t\t} else if (reportId == 'temp') {\r\n\t\t\t\t// load the report from the temp place\r\n\t\t\t\treport = CabinReportLocalEditFactory.getCabinReportLocalEditFromTemp();\r\n\r\n\t\t\t\tif (report == null) {\r\n\t\t\t\t\t// since we could not load the temp report, delete it\r\n\t\t\t\t\tCabinReportLocalEditFactory.deleteTempReport();\r\n\r\n\t\t\t\t\tbootbox.alert(\"

Warning

Unable to load temporary log.
No temporary log found in this device or the report was corrupted\",\r\n\t\t\t\t\t\tfunction () {\r\n\t\t\t\t\t\t\t$location.path(\"/\");\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// load the report\r\n\t\t\t\treport = CabinReportLocalEditFactory.getCabinReportLocalEdit(reportId);\r\n\t\t\t\tif (report == null) {\r\n\t\t\t\t\tbootbox.alert(\"

Warning

Unable to load the requested log.
This entry does not exist in this device, our its data are corrupted and the entry is unusable.\",\r\n\t\t\t\t\t\tfunction () {\r\n\t\t\t\t\t\t\t$location.path(\"/\");\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t)\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t$scope.report = report;\r\n\t\t\tinfoSaveOperation('discard')\r\n\t\t}\r\n\r\n\t\t$scope.state = 'report';\r\n\t\t$scope.logged_user_info = user.aimsId + ' - ' + user.name;\r\n\t\t$scope.isSecure = UserFactory.isSecure();\r\n\r\n\t\t// new / edit existing / load from temp\r\n\t\tif (reportId.startsWith('new:')) {\r\n\t\t\tvar flightId = $routeParams.flightId;\r\n\t\t\t// create a new report\r\n\t\t\tvar newLocalReport = CabinReportLocalEditCreatorFactory.createNewLocalReportForFlight(flightId);\r\n\r\n\t\t\tif (newLocalReport == null) {\r\n\t\t\t\tbootbox.alert(\"

Attention

Unable to create a new log!
Available pool of resources has been depleted and you need to synchronize with the server to renew it.\",\r\n\t\t\t\t\tfunction () {\r\n\t\t\t\t\t\t$location.path(\"/\");\r\n\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t}\r\n\t\t\t\t);\r\n\t\t\t\treturn;\r\n\t\t\t} else {\r\n\t\t\t\t// load the new report\r\n\t\t\t\treport = newLocalReport;\r\n\t\t\t}\r\n\t\t} else if (reportId == 'temp') {\r\n\t\t\t// load the report from the temp place\r\n\t\t\treport = CabinReportLocalEditFactory.getCabinReportLocalEditFromTemp();\r\n\t\t\tif (report == null) {\r\n\t\t\t\t// since we could not load the temp report, delete it\r\n\t\t\t\tCabinReportLocalEditFactory.deleteTempReport();\r\n\t\t\t\tbootbox.alert(\"

Warning

Unable to load temporary log.
No temporary log found in this device or the report was corrupted\",\r\n\t\t\t\t\tfunction () {\r\n\t\t\t\t\t\t$location.path(\"/\");\r\n\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t}\r\n\t\t\t\t);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t// load the report\r\n\t\t\treport = CabinReportLocalEditFactory.getCabinReportLocalEdit(reportId);\r\n\t\t\tif (report == null) {\r\n\t\t\t\tbootbox.alert(\"

Warning

Unable to load the requested log.
This entry does not exist in this device, our its data are corrupted and the entry is unusable.\",\r\n\t\t\t\t\tfunction () {\r\n\t\t\t\t\t\t$location.path(\"/\");\r\n\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t}\r\n\t\t\t\t);\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t$scope.countDHC = 0;\r\n\t\tif (report.crew) $scope.countDHC = report.crew.filter(function (item) {\r\n\t\t\treturn (item.isDHC == true);\r\n\t\t}).length;\r\n\r\n\t\t//Additional feedback\r\n\t\tif (report.crew) {\r\n\t\t\tvar crewNeedsAdditionalFeedback = [];\r\n\t\t\tvar crewMemberNeedsAdditionalFeedback = report.crew.filter(x => x.needsAdditionalFeedback);\r\n\t\t\tcrewNeedsAdditionalFeedback.push(crewMemberNeedsAdditionalFeedback);\r\n\r\n\t\t\tif (crewNeedsAdditionalFeedback.length > 0) {\r\n\t\t\t\tvar crewNeedsAdditionalFeedbackFlatten = crewNeedsAdditionalFeedback.flat();\r\n\t\t\t\tfor (var i = 0; i < crewNeedsAdditionalFeedbackFlatten.length; i++) {\r\n\t\t\t\t\treport.CCMSCrewPositions.find(x => x.CrewId == crewNeedsAdditionalFeedbackFlatten[i].aimsId).needsAdditionalFeedback = true;\r\n\t\t\t\t\treport.CCMSCrewPositions.find(x => x.CrewId == crewNeedsAdditionalFeedbackFlatten[i].aimsId).AdditionalFeedback = crewNeedsAdditionalFeedbackFlatten[i].AdditionalFeedback;\r\n\t\t\t\t\treport.CCMSCrewPositions.find(x => x.CrewId == crewNeedsAdditionalFeedbackFlatten[i].aimsId).AdditionalFeedbackId = crewNeedsAdditionalFeedbackFlatten[i].AdditionalFeedback.Id;\r\n\t\t\t\t\treport.CCMSCrewPositions.find(x => x.CrewId == crewNeedsAdditionalFeedbackFlatten[i].aimsId).FeedbackAuthorName = crewNeedsAdditionalFeedbackFlatten[i].AdditionalFeedback.FeedbackAuthorName;\r\n\t\t\t\t\treport.CCMSCrewPositions.find(x => x.CrewId == crewNeedsAdditionalFeedbackFlatten[i].aimsId).Route = report.Route;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// update totals and set to scope\r\n\t\treport.updateTotals();\r\n\t\t$scope.report = report;\r\n\r\n\t\t$scope.infosaveaction = false;\r\n\r\n\r\n\t\t// save the report to a temp place\r\n\t\tif (report.Status != 'synched')\r\n\t\t\treport.saveReportAsTemp();\r\n\r\n\t\t// set editing page to report\r\n\t\tSettingsMain.setEditingPage('report');\r\n\r\n\t\tif (report && report.ScheduledArrival) {\r\n\t\t\tvar nowTimeStamp = moment.utc().valueOf();\r\n\t\t\tvar schedullDepartureTimestamp = new Date(report.ScheduledArrival).getTime();\r\n\r\n\t\t\t$scope.isFuture = nowTimeStamp < schedullDepartureTimestamp;\r\n\t\t}\r\n\t\t$scope.showCompleted = showCompleted;\r\n\t\t$scope.showAll = showAll;\r\n\t\t$scope.compressedMode = false;\r\n\t\tfunction showCompleted() {\r\n\t\t\tif (!$scope.report.BarTrolleys || $scope.report.BarTrolleys.length == 0)\r\n\t\t\t\t$scope.panels.bars.visible = false;\r\n\r\n\t\t\tif (!$scope.report.MedicalIncidents || !(report.FirstAidKits.length > 0 || report.MedicalIncidents.length > 0))\r\n\t\t\t\t$scope.panels.medical.visible = false;\r\n\r\n\t\t\tif (!$scope.report.ItemsFoundSectionHasValue)\r\n\t\t\t\t$scope.panels.security.visible = false;\r\n\r\n\t\t\tif (!$scope.report.SpecialMealIssues || $scope.report.SpecialMealIssues.length == 0)\r\n\t\t\t\t$scope.panels.special.visible = false;\r\n\r\n\t\t\tif (!$scope.report.Supplies || $scope.report.Supplies.length == 0)\r\n\t\t\t\t$scope.panels.supplies.visible = false;\r\n\r\n\t\t\tif (!$scope.report.TravelValueSeals || !(report.TravelValueSeals.length > 0 || report.TravelValueIncomplete || (report.TravelValueRemarks != null && report.TravelValueRemarks != '')))\r\n\t\t\t\t$scope.panels.travel.visible = false;\r\n\r\n\t\t\tif (!$scope.report.UMSectionHasValue)\r\n\t\t\t\t$scope.panels.um.visible = false;\r\n\r\n\t\t\tif ($scope.report.ActiveVariousIssues == 0)\r\n\t\t\t\t$scope.panels.various.visible = false;\r\n\r\n\t\t\tif (!$scope.report.WaterSectionHasValue)\r\n\t\t\t\t$scope.panels.water.visible = false;\r\n\r\n\t\t\tif (!($scope.report.UpgradedPassengers.length > 0))\r\n\t\t\t\t$scope.panels.upgd.visible = false;\r\n\r\n\t\t\tif (!($scope.report.ChangedSeats.length > 0))\r\n\t\t\t\t$scope.panels.changedSeats.visible = false;\r\n\r\n\t\t\tif (!($scope.report.IncompleteServices.length > 0))\r\n\t\t\t\t$scope.panels.incompleteServices.visible = false;\r\n\r\n\t\t\tif (!$scope.report.BoardingTimes || (report.BoardingTimesRemarks != null && report.BoardingTimesRemarks != ''))\r\n\t\t\t\t$scope.panels.travel.visible = false;\r\n\r\n\t\t\tif (!$scope.report.LuggageSectionHasValue)\r\n\t\t\t\t$scope.panels.luggage.visible = false;\r\n\r\n\r\n\t\t\t$scope.panels.leg.open = !$scope.panels.leg.open;\r\n\t\t\t$scope.compressedMode = true;\r\n\t\t}\r\n\r\n\r\n\r\n\t\tfunction showAll() {\r\n\t\t\t$scope.panels.bars.visible = true;\r\n\t\t\t$scope.panels.medical.visible = true;\r\n\t\t\t$scope.panels.security.visible = true;\r\n\t\t\t$scope.panels.special.visible = true;\r\n\t\t\t$scope.panels.supplies.visible = true;\r\n\t\t\t$scope.panels.travel.visible = true;\r\n\t\t\t$scope.panels.various.visible = true;\r\n\t\t\t$scope.panels.water.visible = true;\r\n\t\t\t$scope.panels.groundServices.visible = true;\r\n\t\t\t$scope.panels.upgd.visible = true;\r\n\t\t\t$scope.panels.changedSeats.visible = true;\r\n\t\t\t$scope.panels.incompleteServices.visible = true;\r\n\t\t\t$scope.panels.boardingTimes.visible = true;\r\n\t\t\t$scope.panels.disembarkationTimes.visible = true;\r\n\t\t\t$scope.panels.luggage.visible = true;\r\n\r\n\t\t\t$scope.panels.leg.open = !$scope.panels.leg.open;\r\n\t\t\t$scope.compressedMode = false;\r\n\t\t}\r\n\r\n\r\n\t\t$scope.panels = {\r\n\t\t\tshowOnlyOne: true,\r\n\t\t\tleg: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: true,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\treturn report.IsValid ? 'panel-green' : 'panel-orange';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tinfo: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tccms: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\treturn (!report.CCMSCrewPositionsIsValid || report.CCMSCrewPositions.length == 0) ? 'panel-orange' : 'panel-green';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tbars: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (!report.BarTrolleysIsValid)\r\n\t\t\t\t\t\treturn 'panel-orange';\r\n\t\t\t\t\telse if (report.BarTrolleys.length > 0)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tmedical: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (!report.FirstAidKitsIsValid || !report.MedicalIncidentsIsValid)\r\n\t\t\t\t\t\treturn 'panel-orange';\r\n\t\t\t\t\telse if (report.FirstAidKits.length > 0 || report.MedicalIncidents.length > 0)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tsecurity: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (!report.ItemsFoundSectionIsValid)\r\n\t\t\t\t\t\treturn 'panel-orange';\r\n\t\t\t\t\telse if (report.ItemsFoundSectionHasValue)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tspecial: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (!report.SpecialMealIssuesIsValid)\r\n\t\t\t\t\t\treturn 'panel-orange';\r\n\t\t\t\t\telse if (report.SpecialMealIssues.length > 0)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tsupplies: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (!report.SuppliesIsValid)\r\n\t\t\t\t\t\treturn 'panel-orange';\r\n\t\t\t\t\telse if (report.Supplies.length > 0)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\ttravel: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (!report.TravelValueSealsIsValid || !report.TravelValueIncompleteIsValid) /*!report.CashValuesIsValid)*/\r\n\t\t\t\t\t\treturn 'panel-orange';\r\n\t\t\t\t\telse if (report.TravelValueSeals.length > 0 || report.TravelValueIncomplete || (report.TravelValueRemarks != null && report.TravelValueRemarks != ''))\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tum: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (!report.UMSectionIsValid)\r\n\t\t\t\t\t\treturn 'panel-orange';\r\n\t\t\t\t\telse if (report.UMSectionHasValue)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tvarious: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (report.WarningVariousIssues > 0)\r\n\t\t\t\t\t\treturn 'panel-orange';\r\n\t\t\t\t\telse if (report.ActiveVariousIssues > 0)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\twater: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (!report.WaterSectionIsValid)\r\n\t\t\t\t\t\treturn 'panel-orange';\r\n\t\t\t\t\telse if (report.WaterSectionHasValue)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tgroundServices: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (report.GroundServicesSectionHasValue)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tupgd: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (report.UpgradedPassengers.length > 0)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tchangedSeats: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (report.ChangedSeats.length > 0)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tincompleteServices: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (report.IncompleteServices.length > 0)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tboardingTimes: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (report.FirstPaxTime && report.LastPaxTime)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tdisembarkationTimes: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (report.FirstPaxDisembarkationTime && report.LastPaxDisembarkationTime)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t},\r\n\t\t\tluggage: {\r\n\t\t\t\tvisible: true,\r\n\t\t\t\topen: false,\r\n\t\t\t\tcssClass: function () {\r\n\t\t\t\t\tif (report.LuggageNumber > 0)\r\n\t\t\t\t\t\treturn 'panel-green';\r\n\t\t\t\t\telse\r\n\t\t\t\t\t\treturn 'panel-default';\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\t$scope.panelClicked = function (e) {\r\n\t\t\tvar q = $(e.currentTarget);\r\n\t\t\tif (q.hasClass('panel-sector'))\r\n\t\t\t\tq = q.find('textarea');\r\n\t\t\telse\r\n\t\t\t\tq = q.parent('.panel-sector').find('textarea');\r\n\t\t\tq.each(function (index, item) {\r\n\t\t\t\tautoAdjustTextarea(item);\r\n\t\t\t});\r\n\t\t}\r\n\t\tvar flight = FlightFactory.getFlightFromStorage(report.FlightId);\r\n\r\n\t\tif (flight == null) {\r\n\t\t\tflight = FlightFactory.getLocalFlightFromStorage(report.FlightId)\r\n\t\t}\r\n\r\n\t\tif (flight == null) {\r\n\t\t\thandleIfReport(report);\r\n\t\t\tSettingsMain.setEditingPage(null);\r\n\t\t\t$location.path(\"/\");\r\n\t\t}\r\n\r\n\t\tif (flight != null) {\r\n\t\t\t$scope.flight = flight;\r\n\t\t\tvar dateObj = new Date(flight.FlightDate);\r\n\t\t\t$scope.waterSectionRequired = (dateObj.getDate() == 1 || dateObj.getDate() == 15);\r\n\t\t}\r\n\r\n\t\tif (flight == null) {\r\n\t\t\thandleIfReport(report);\r\n\t\t\tSettingsMain.setEditingPage(null);\r\n\t\t\t$location.path(\"/\");\r\n\t\t}\r\n\r\n\t\tif (flight != null) {\r\n\t\t\t$scope.flight = flight;\r\n\t\t\tvar dateObj = new Date(flight.FlightDate);\r\n\t\t\t$scope.waterSectionRequired = (dateObj.getDate() == 1 || dateObj.getDate() == 15);\r\n\t\t}\r\n\r\n\t\t$scope.sendCustomerIncident = sendCustomerIncident;\r\n\r\n\t\t/**\r\n\t\t * Send application Customer Incident information\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction sendCustomerIncident(description, label, photos) {\r\n\r\n\t\t\tvar image = photos.length > 0 ? photos[0].PhotoData : null;\r\n\t\t\tvar flightDate = new Date(flight.FlightDate);\r\n\t\t\tvar flightDescription = flight.FlightNo + \" \" + flight.Departure + \"-\" + flight.Arrival + \" \" + (flightDate.getUTCDate() > 10 ? flightDate.getUTCDate() : \"0\" + flightDate.getUTCDate()) + \"-\" + (flightDate.getUTCMonth() > 9 ? (flightDate.getUTCMonth() + 1) : \"0\" + (flightDate.getUTCMonth() + 1)) + \"-\" + flightDate.getUTCFullYear();\r\n\r\n\r\n\t\t\tvar customerIncident = { flightDescription: flightDescription, question: label, description: description, image: image };\r\n\r\n\t\t\tvar modalInstance = $uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgCustomerIncidentSend.html',\r\n\t\t\t\tcontroller: 'CustomerModalCtrl',\r\n\t\t\t\tsize: 'md',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tcustomerIncident: function () {\r\n\t\t\t\t\t\treturn customerIncident;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t}\r\n\r\n\t\t//Clear Fields Functionality\r\n\t\t$scope.clearItemsFoundDescription = clearItemsFoundDescription;\r\n\t\t$scope.clearItemsFoundAgent = clearItemsFoundAgent;\r\n\t\t$scope.clearItemsFoundSignature = clearItemsFoundSignature;\r\n\t\t$scope.clearUMDescription = clearUMDescription;\r\n\t\t$scope.clearUMAgent = clearUMAgent;\r\n\t\t$scope.clearUMSignature = clearUMSignature;\r\n\t\t$scope.clearWaterRemarks = clearWaterRemarks;\r\n\t\t$scope.clearTravelValueRemarks = clearTravelValueRemarks;\r\n\t\t$scope.clearBoardingTimesRemarks = clearBoardingTimesRemarks;\r\n\t\t$scope.clearDisembarkationTimesRemarks = clearDisembarkationTimesRemarks;\r\n\t\t$scope.clearRemarks = clearRemarks;\r\n\t\t$scope.clearCrewRemarks = clearCrewRemarks;\r\n\t\t$scope.clearVariousItemRemarks = clearVariousItemRemarks;\r\n\t\t$scope.clearBarSealsPhotoRemarks = clearBarSealsPhotoRemarks;\r\n\t\t$scope.clearLuggageDescription = clearLuggageDescription;\r\n\t\t$scope.reportItemValueChanged = reportItemValueChanged;\r\n\t\t$scope.cancelClicked = cancelClicked;\r\n\t\t$scope.saveClicked = saveClicked;\r\n\t\t$scope.saveDraftClicked = saveDraftClicked;\r\n\t\t$scope.deleteReportClicked = deleteReportClicked;\r\n\t\t//update report when a report item is changed\r\n\t\t$scope.reportChanged = reportChanged;\r\n\t\t// Incomplete Travel\r\n\t\t// Get list of reasons\r\n\t\t$scope.reportTravelValueIncompleteReasons = TravelValueIncompleteReasonFactory.getReasonsFromStorage();\r\n\t\t$scope.plusTravelValueIncompleteRow = plusTravelValueIncompleteRow;\r\n\t\t$scope.minusTravelValueIncompleteRow = minusTravelValueIncompleteRow;\r\n\t\t$scope.reportTravelIncompleteChanged = reportTravelIncompleteChanged;\r\n\t\t//UMnumber\r\n\t\t$scope.plusUMNumber = plusUMNumber;\r\n\t\t$scope.minusUMNumber = minusUMNumber;\r\n\t\t$scope.clearUMNumber = clearUMNumber;\r\n\t\t$scope.waterUpliftActions = WaterUpliftActionFactory.getWaterUpliftActionsFromStorageAsStrings();\r\n\t\t//copy positions from previous leg, to minimize input\r\n\t\t//normally, ac performs several legs in a row with the same crew, each at the same position on all legs\r\n\t\t$scope.copyCcmsPositions = copyCcmsPositions;\r\n\t\t// List of ccms position of this A/C\r\n\t\t$scope.reportCCMSPositions = reportCCMSPositions\r\n\t\t//Modals\r\n\t\t// Bars Trolleys\r\n\t\t$scope.addNewBarTrolley = addNewBarTrolley;\r\n\t\t$scope.editBarTrolley = editBarTrolley;\r\n\t\t$scope.deleteBarTrolley = deleteBarTrolley;\r\n\t\t// Luggage Number\r\n\t\t$scope.plusLuggageNumber = plusLuggageNumber;\r\n\t\t$scope.minusLuggageNumber = minusLuggageNumber;\r\n\t\t$scope.clearLuggageNumber = clearLuggageNumber;\r\n\t\t// CCMS\r\n\t\t$scope.addNewCCMSCrewPosition = addNewCCMSCrewPosition;\r\n\t\t$scope.editCCMSCrewPosition = editCCMSCrewPosition;\r\n\t\t$scope.deleteCCMSCrewPosition = deleteCCMSCrewPosition;\r\n\r\n\t\t$scope.user = UserFactory.getUser();\r\n\t\t$scope.showFeedback = [];\r\n\t\t$scope.toggleAdditionalFeedback = function ($index) {\r\n\t\t\t$scope.showFeedback[$index] = !$scope.showFeedback[$index];\r\n\t\t}\r\n\t\t//CCMS: Show(toggle) CrewComments\r\n\t\t$scope.showCrewComments = function (item) {\r\n\t\t\tif (item.HasCrewComments == true && !item.CrewComments) {\r\n\t\t\t\titem.HasCrewComments = false;\r\n\t\t\t}\r\n\t\t\t//Clear comments\r\n\t\t\telse if (item.HasCrewComments == true) {\r\n\t\t\t\tbootbox.dialog({\r\n\t\t\t\t\tmessage: \"Please confirm that you wish to clear the comments\",\r\n\t\t\t\t\ttitle: \"Attention\",\r\n\t\t\t\t\tbuttons: {\r\n\t\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\tok: {\r\n\t\t\t\t\t\t\tlabel: \"Ok\",\r\n\t\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\t\t$timeout(\r\n\t\t\t\t\t\t\t\t\tfunction () {\r\n\t\t\t\t\t\t\t\t\t\titem.CrewComments = null;\r\n\t\t\t\t\t\t\t\t\t\titem.HasCrewComments = false;\r\n\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t} else {\r\n\t\t\t\titem.HasCrewComments = true;\r\n\t\t\t}\r\n\t\t};\r\n\r\n\t\t//Additional Feedback: Show(toggle) Crew Comments\r\n\t\t$scope.showAdditionalFeedback = function (item) {\r\n\t\t\tif (item.HasAdditionalFeedbackComments == true && !item.CrewComments) {\r\n\t\t\t\titem.HasAdditionalFeedbackComments = false;\r\n\t\t\t}\r\n\t\t\t//Clear comments\r\n\t\t\telse\r\n\t\t\t\tif (item.HasAdditionalFeedbackComments == true) {\r\n\t\t\t\t\tbootbox.dialog({\r\n\t\t\t\t\t\tmessage: \"Please confirm that you wish to clear the comments\",\r\n\t\t\t\t\t\ttitle: \"Attention\",\r\n\t\t\t\t\t\tbuttons: {\r\n\t\t\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t\t\t},\r\n\t\t\t\t\t\t\tok: {\r\n\t\t\t\t\t\t\t\tlabel: \"Ok\",\r\n\t\t\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\t\t\t$timeout(\r\n\t\t\t\t\t\t\t\t\t\tfunction () {\r\n\t\t\t\t\t\t\t\t\t\t\titem.CrewComments = null;\r\n\t\t\t\t\t\t\t\t\t\t\titem.HasAdditionalFeedbackComments = false;\r\n\t\t\t\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t});\r\n\t\t\t\t} else {\r\n\t\t\t\t\titem.HasAdditionalFeedbackComments = true;\r\n\t\t\t\t}\r\n\t\t};\r\n\r\n\t\t// Flight Detail\r\n\t\t$scope.openFlightDetailModal = openFlightDetailModal;\r\n\t\t// First Aid Kits\r\n\t\t$scope.addNewFirstAidKit = addNewFirstAidKit;\r\n\t\t$scope.editFirstAidKit = editFirstAidKit;\r\n\t\t$scope.deleteFirstAidKit = deleteFirstAidKit;\r\n\t\t// Medical Incidents\r\n\t\t$scope.addNewMedicalIncident = addNewMedicalIncident;\r\n\t\t$scope.editMedicalIncident = editMedicalIncident;\r\n\t\t$scope.deleteMedicalIncident = deleteMedicalIncident;\r\n\t\t// Special Meals\r\n\t\t$scope.addNewSpecialMealIssue = addNewSpecialMealIssue;\r\n\t\t$scope.editSpecialMealIssue = editSpecialMealIssue;\r\n\t\t$scope.deleteSpecialMealIssue = deleteSpecialMealIssue;\r\n\t\t// Supplies\r\n\t\t$scope.addNewSupply = addNewSupply;\r\n\t\t$scope.editSupply = editSupply;\r\n\t\t$scope.deleteSupply = deleteSupply;\r\n\t\t//UPGDs\r\n\t\t$scope.addNewUPGD = addNewUPGD;\r\n\t\t$scope.editUPGD = editUPGD;\r\n\t\t$scope.deleteUPGD = deleteUPGD;\r\n\t\t//Changed seats\r\n\t\t$scope.addNewChangedSeat = addNewChangedSeat;\r\n\t\t$scope.editChangedSeat = editChangedSeat;\r\n\t\t$scope.deleteChangedSeat = deleteChangedSeat;\r\n\t\t// Travel value seal \r\n\t\t$scope.addNewTravelValueSeal = addNewTravelValueSeal;\r\n\t\t$scope.editTravelValueSeal = editTravelValueSeal;\r\n\t\t$scope.deleteTravelValueSeal = deleteTravelValueSeal;\r\n\t\t// Incomplete in-flight Services\r\n\t\t$scope.addIncompleteService = addIncompleteService;\r\n\t\t$scope.editIncompleteService = editIncompleteService;\r\n\t\t$scope.deleteIncompleteService = deleteIncompleteService;\r\n\t\t// Attatch Photo\r\n\t\t$scope.attachPhotoOnVariousItem = attachPhotoOnVariousItem;\r\n\t\t$scope.attachPhotoOnBarTrolley = attachPhotoOnBarTrolley;\r\n\r\n\t\t$scope.addNewEMKFirstAidKit = addNewEMKFirstAidKit;\r\n\r\n\t\t// Additional Feedback\r\n\t\t$scope.addAdditionalFeedback = addAdditionalFeedback;\r\n\r\n\t\t//Clear functions \r\n\t\t/**\r\n\t\t * Clear Selected Field\r\n\t\t * @memberof ReportCtrl\r\n\t\t * @param {object} target the object whose field we want to clear\r\n\t\t * @param {string} fieldName the field Name to clear\r\n\t\t */\r\n\t\tfunction clearField(target, fieldName) {\r\n\t\t\tif (target[fieldName] == undefined || target[fieldName] == null || target[fieldName] == '') return false;\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Please confirm that you wish to clear this field\",\r\n\t\t\t\ttitle: \"Attention\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tok: {\r\n\t\t\t\t\t\tlabel: \"Ok\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\ttarget[fieldName] = null;\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\t\t\t\t\t\t\t//TODO REMOVE COMMENT DANGEROUS $SCOPE $APPLY\r\n\t\t\t\t\t\t\t//$scope.$apply();\r\n\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Clear itemsFoundDescription\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearItemsFoundDescription() {\r\n\t\t\tclearField($scope.report, \"ItemsFoundDescription\");\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear itemsFoundAgent\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearItemsFoundAgent() {\r\n\t\t\tclearField($scope.report, \"ItemsFoundAgent\");\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear itemsFoundSignature\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearItemsFoundSignature() {\r\n\t\t\tclearField($scope.report, \"ItemsFoundSignature\");\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear UMDescription\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearUMDescription() {\r\n\t\t\tclearField($scope.report, \"UMDescription\");\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Clear UMAgent\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearUMAgent() {\r\n\t\t\tclearField($scope.report, \"UMAgent\");\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear UMSignature\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearUMSignature() {\r\n\t\t\tclearField($scope.report, \"UMSignature\");\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Clear LuggageDescription\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearLuggageDescription() {\r\n\t\t\tclearField($scope.report, \"LuggageDescription\");\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear WaterRemarks\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearWaterRemarks() {\r\n\t\t\tclearField($scope.report, \"WaterUpliftRemarks\");\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear Travel Value Remarks\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearTravelValueRemarks() {\r\n\t\t\tclearField($scope.report, \"TravelValueRemarks\");\r\n\t\t}\r\n\t\t/**\r\n * Clear boarding times Remarks\r\n * @memberof ReportCtrl\r\n */\r\n\t\tfunction clearBoardingTimesRemarks() {\r\n\t\t\tclearField($scope.report, \"BoardingTimesRemarks\");\r\n\t\t}\r\n\t\t/**\r\n* Clear disembarkation times Remarks\r\n* @memberof ReportCtrl\r\n*/\r\n\t\tfunction clearDisembarkationTimesRemarks() {\r\n\t\t\tclearField($scope.report, \"DisembarkationTimesRemarks\");\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear Remarks\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearRemarks() {\r\n\t\t\tclearField($scope.report, \"Remarks\");\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear Crew Remarks\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearCrewRemarks() {\r\n\t\t\tclearField($scope.report, \"CrewRemarks\");\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear Various Item Remarks\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearVariousItemRemarks(item) {\r\n\t\t\tif (item != null) {\r\n\t\t\t\tclearField(item, \"ItemValue\");\r\n\t\t\t}\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear Various Item Remarks\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearBarSealsPhotoRemarks(item) {\r\n\t\t\tif (item != null) {\r\n\t\t\t\tclearField(item, \"PhotoRemarks\");\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * When the user types a value into a report item updates totals of the report\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction reportItemValueChanged() {\r\n\r\n\t\t\t// update the report totals\r\n\t\t\treport.updateTotals();\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Go to calendar and reset report\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction cancelClicked() {\r\n\t\t\t//store report details\r\n\t\t\tvar guid = report.ReportGuid;\r\n\t\t\tvar status = report.Status;\r\n\r\n\t\t\t// delete the temp report\r\n\t\t\tCabinReportLocalEditFactory.deleteTempReport();\r\n\r\n\t\t\t//reuse guid if this was a new report\r\n\t\t\tif (status == 'pending')\r\n\t\t\t\tReportGuidFactory.restoreGuid(report.ReportGuid);\r\n\r\n\t\t\t// set editing page to none\r\n\t\t\tSettingsMain.setEditingPage(null);\r\n\r\n\t\t\t// go to dashboard\r\n\t\t\t$location.path(\"/\");\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Show information about the save action\r\n\t\t * @memberof ReportCtrl\r\n\t\t * @param {string} state The action of the save completed or draft or discard\r\n\t\t */\r\n\t\tfunction infoSaveOperation(state) {\r\n\t\t\tif (state == 'completed') {\r\n\t\t\t\t$scope.infosaveactiontype = state;\r\n\t\t\t\t$scope.infosaveaction = true;\r\n\t\t\t} else if (state == 'draft') {\r\n\t\t\t\t$scope.infosaveactiontype = state;\r\n\t\t\t\t$scope.infosaveaction = true\r\n\t\t\t} else if (state == 'discard') {\r\n\t\t\t\t$scope.infosaveactiontype = state;\r\n\t\t\t\t$scope.infosaveaction = true\r\n\t\t\t}\r\n\r\n\t\t\t$timeout(function () {\r\n\t\t\t\t$scope.infosaveaction = false;\r\n\t\t\t}, 5000);\r\n\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Save Completed and Go to calendar\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction saveClicked() {\r\n\t\t\t$scope.groomingReports = GroomingCategoriesFactory.collectGroomingReports($scope.groomingReportsByCrew)\r\n\t\t\tGroomingCategoriesFactory.saveGroomingReports($scope.groomingReportsByCrew);\r\n\r\n\t\t\treport.GroomingReports = $scope.groomingReports;\r\n\t\t\t\r\n\t\t\t// save the report\r\n\t\t\treport.Status = 'completed';\r\n\t\t\treport.saveReport();\r\n\t\t\tFlightFactory.updateFlightFromReport(report);\r\n\r\n\t\t\t// delete the temp report\r\n\t\t\tCabinReportLocalEditFactory.deleteTempReport();\r\n\r\n\t\t\tCrewAssessmentFactory.updateCrewMembers(report.CCMSCrewPositions, report.Route, report.DutyDate);\r\n\t\t\t// set editing page to none\r\n\t\t\tSettingsMain.setEditingPage(null);\r\n\t\t\tinfoSaveOperation(report.Status);\r\n\r\n\r\n\t\t\t// go to flight info\r\n\t\t\t$location.path('/flightinfo/' + report.FlightId);\r\n\t\t}\r\n\t\t/**\r\n\t\t * Save Draft\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction saveDraftClicked() {\r\n\t\t\t// save the report\r\n\t\t\treport.Status = 'draft';\r\n\t\t\treport.saveReport();\r\n\t\t\tFlightFactory.updateFlightFromReport(report);\r\n\t\t\tCrewAssessmentFactory.updateCrewMembers(report.CCMSCrewPositions, report.Route, report.DutyDate);\r\n\r\n\t\t\t// delete the temp report\r\n\t\t\tCabinReportLocalEditFactory.deleteTempReport();\r\n\r\n\t\t\t// set editing page to none\r\n\t\t\tSettingsMain.setEditingPage(null);\r\n\t\t\tinfoSaveOperation(report.Status);\r\n\t\t\t// go to dashboard\r\n\t\t\t// $location.path(\"/\");\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Delete Report\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction deleteReportClicked() {\r\n\t\t\tvar status = report.status;\r\n\t\t\tvar title = \"Warning\";\r\n\t\t\tif (status == 'synched') {\r\n\t\t\t\ttitle = \"Attention\";\r\n\t\t\t}\r\n\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Please confirm that you wish to reset this Cabin Report.\",\r\n\t\t\t\ttitle: \"\" + title + \"\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tdanger: {\r\n\t\t\t\t\t\tlabel: \"Reset Cabin Report\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\t//store report details\r\n\t\t\t\t\t\t\tvar guid = report.ReportGuid;\r\n\t\t\t\t\t\t\tvar status = report.Status;\r\n\r\n\t\t\t\t\t\t\t// remove report from temp location and\r\n\t\t\t\t\t\t\t// possibly from permanent location\r\n\t\t\t\t\t\t\tCabinReportLocalEditFactory.deleteReport(report.ReportGuid);\r\n\t\t\t\t\t\t\tCrewAssessmentFactory.updateCrewMembers(report.CCMSCrewPositions, report.Route, report.DutyDate);\r\n\r\n\t\t\t\t\t\t\t// delete the temp report\r\n\t\t\t\t\t\t\tCabinReportLocalEditFactory.deleteTempReport();\r\n\r\n\r\n\t\t\t\t\t\t\tFlightFactory.updateFlightFromReport(report);\r\n\t\t\t\t\t\t\t//reuse guid if this was report was never sent to the server\r\n\t\t\t\t\t\t\tif (status == 'draft' || status == 'completed')\r\n\t\t\t\t\t\t\t\tReportGuidFactory.restoreGuid(report.ReportGuid);\r\n\r\n\t\t\t\t\t\t\t// set editing page to none\r\n\t\t\t\t\t\t\tSettingsMain.setEditingPage(null);\r\n\t\t\t\t\t\t\t// next code moves user to main page\r\n\t\t\t\t\t\t\t$timeout(function () {\r\n\t\t\t\t\t\t\t\tif ($location.path() == \"/report/temp\") {\r\n\t\t\t\t\t\t\t\t\t$scope.openReport();\r\n\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t$route.reload();\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t})\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * increase row no of travel value\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction plusTravelValueIncompleteRow() {\r\n\t\t\tif (!report.TravelValueIncompleteRow && report.TravelValueIncompleteRow != 0)\r\n\t\t\t\treport.TravelValueIncompleteRow = 0;\r\n\t\t\telse\r\n\t\t\t\treport.TravelValueIncompleteRow++;\r\n\t\t\tif (report.TravelValueIncompleteRow > 99) report.TravelValueIncompleteRow = 99;\r\n\t\t\t$scope.reportItemValueChanged();\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * decrease row no of travel value\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction minusTravelValueIncompleteRow() {\r\n\t\t\tif (!report.TravelValueIncompleteRow && report.TravelValueIncompleteRow != 0)\r\n\t\t\t\treport.TravelValueIncompleteRow = 0;\r\n\t\t\telse\r\n\t\t\t\treport.TravelValueIncompleteRow--;\r\n\t\t\tif (report.TravelValueIncompleteRow < 0) report.TravelValueIncompleteRow = 0;\r\n\t\t\t$scope.reportItemValueChanged();\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * travel value changed\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction reportTravelIncompleteChanged() {\r\n\t\t\tif (!report.TravelIncomplete) {\r\n\t\t\t\treport.TravelValueIncompleteRow = null;\r\n\t\t\t\treport.TravelValueIncompleteReason = null;\r\n\t\t\t}\r\n\t\t\t$scope.reportItemValueChanged();\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * When report changes run to update the item\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction reportChanged(item) {\r\n\r\n\t\t\t// put preset comments\r\n\t\t\tif (item != null) {\r\n\t\t\t\tif (item.PresetComments != null) {\r\n\t\t\t\t\tif ((item.ItemValue == null) || (item.ItemValue == '')) {\r\n\t\t\t\t\t\titem.ItemValue = item.PresetComments;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// update the report totals\r\n\t\t\treport.updateTotals();\r\n\r\n\t\t\t// save the report to a temp place\r\n\t\t\tif (report.Status != 'synched')\r\n\t\t\t\treport.saveReportAsTemp();\r\n\t\t}\r\n\r\n\t\t//CCMS\r\n\t\t/**\r\n\t\t * make the ccms positions\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction reportCCMSPositions() {\r\n\t\t\tvar reportCCMSPositions = new Array();\r\n\t\t\tvar allCCMSPositions = CCMSFactory.getCCMSFromStorage();\r\n\t\t\tfor (var i = 0; i < allCCMSPositions.length; i++) {\r\n\r\n\t\t\t\t// find the positions for this aircraft type\r\n\t\t\t\tif (allCCMSPositions[i].Aircraft == report.AcType) {\r\n\r\n\t\t\t\t\tfor (var j = 0; j < allCCMSPositions[i].Positions.length; j++) {\r\n\r\n\t\t\t\t\t\treportCCMSPositions.push(allCCMSPositions[i].Positions[j].Position);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn reportCCMSPositions;\r\n\t\t}\r\n\r\n\r\n\t\t/**\r\n\t\t * Open confirmation modal for coping ccms \r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction copyCcmsPositions() {\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Copy CCMS positions from previous leg?
Attention: Any current CCMS data will be overwritten\",\r\n\t\t\t\ttitle: \"CCMS Copy\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\tcopyCcmsPositionsFinal();\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * copy positions from previous leg, to minimize input, normally, ac performs several legs in a row with the same crew, each at the same position on all legs \r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction copyCcmsPositionsFinal() {\r\n\t\t\tif (report.CCMSCrewPositions == null || report.CCMSCrewPositions.length == 0) return;\r\n\t\t\tvar guid = report.ReportGuid;\r\n\t\t\tvar ac = report.AcTailNo;\r\n\t\t\tvar dt = report.ScheduledDepartureDateUTC;\r\n\t\t\tvar tm = report.ScheduledDepartureTimeUTC;\r\n\t\t\tvar previousCcms = CabinReportLocalEditFactory.getPreviousCabinReportCcmsPositions(guid, ac, dt, tm);\r\n\t\t\tif (previousCcms != null && previousCcms.length > 0) {\r\n\t\t\t\tvar posX, posI, found;\r\n\t\t\t\t//TODO: Special treatment for manual entries: Add new ones, update existing will data (Id, Initials, Name, Position, CCMS)\r\n\t\t\t\t//loop all previous report positions\r\n\t\t\t\tfor (var i = 0; i < previousCcms.length; i++) {\r\n\t\t\t\t\tposI = previousCcms[i];\r\n\t\t\t\t\tfound = false;\r\n\t\t\t\t\t//loop all report positions\r\n\t\t\t\t\tfor (var x = 0; x < report.CCMSCrewPositions.length; x++) {\r\n\t\t\t\t\t\tposX = report.CCMSCrewPositions[x];\r\n\t\t\t\t\t\t//check for match\r\n\t\t\t\t\t\tif ((posX.CrewId != null && posX.CrewId != '' &&\r\n\t\t\t\t\t\t\tposI.CrewId != null && posI.CrewId != '' &&\r\n\t\t\t\t\t\t\tposX.CrewId == posI.CrewId) ||\r\n\t\t\t\t\t\t\t(posX.Initials != null && posX.Initials != '' &&\r\n\t\t\t\t\t\t\t\tposI.Initials != null && posI.Initials != '' &&\r\n\t\t\t\t\t\t\t\tposX.Initials == posI.Initials)) {\r\n\t\t\t\t\t\t\t//copy only if source has CCMS set\r\n\t\t\t\t\t\t\tif (posI.CCMS != null && posI.CCMS != '') {\r\n\t\t\t\t\t\t\t\t//old crew matched to current crew\r\n\t\t\t\t\t\t\t\tposX.CCMS = posI.CCMS;\r\n\t\t\t\t\t\t\t\tfound = true;\r\n\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t//if old record was a manual entry and not found in the current crew list, add it also here as manual\r\n\t\t\t\t\tif (posI.IsManual == true && !found) {\r\n\t\t\t\t\t\t//console.debug(posI);\r\n\t\t\t\t\t\t//console.debug(report);\r\n\t\t\t\t\t\treport.CCMSCrewPositions.push(posI);\r\n\t\t\t\t\t\t//console.debug('Add code to copy manual crew member in this current report crew');\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tvar s = '';\r\n\t\t}\r\n\r\n\t\t//UMNumber\r\n\t\t/**\r\n\t\t * increases UM number \r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction plusUMNumber() {\r\n\t\t\treport.UMNumber++;\r\n\t\t\tif (report.UMNumber > 200) report.UMNumber = 200;\r\n\t\t\t$scope.reportItemValueChanged();\r\n\t\t}\r\n\t\t/**\r\n\t\t * decreases UM number \r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction minusUMNumber() {\r\n\t\t\treport.UMNumber--;\r\n\t\t\tif (report.UMNumber < 0) report.UMNumber = 0;\r\n\t\t\t$scope.reportItemValueChanged();\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear UM number \r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearUMNumber() {\r\n\t\t\treport.UMNumber = 0;\r\n\t\t\t$scope.reportItemValueChanged();\r\n\t\t}\r\n\r\n\t\t//Luggage Number\r\n\t\t/**\r\n\t\t * increases Luggage number \r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction plusLuggageNumber() {\r\n\t\t\treport.LuggageNumber++;\r\n\t\t\tif (report.LuggageNumber > 100) report.LuggageNumber = 100;\r\n\t\t\t$scope.reportItemValueChanged();\r\n\t\t}\r\n\t\t/**\r\n\t\t * decreases Luggage number \r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction minusLuggageNumber() {\r\n\t\t\treport.LuggageNumber--;\r\n\t\t\tif (report.LuggageNumber < 0) report.LuggageNumber = 0;\r\n\t\t\t$scope.reportItemValueChanged();\r\n\t\t}\r\n\t\t/**\r\n\t\t * Clear Luggage number \r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction clearLuggageNumber() {\r\n\t\t\treport.LuggageNumber = 0;\r\n\t\t\t$scope.reportItemValueChanged();\r\n\t\t}\r\n\t\t// Bars Trolleys\r\n\t\t/**\r\n\t\t * define open bar/trolley dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openBarTrolleyModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgBar.html',\r\n\t\t\t\tcontroller: 'BarTrolleyCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tbart: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\treport.BarTrolleys.push(result.Object);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * add new bar/trolley\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addNewBarTrolley() {\r\n\t\t\ttry {\r\n\t\t\t\topenBarTrolleyModal(null);\r\n\t\t\t} catch (e) {\r\n\t\t\t\tLogService.debug(\"template barTrolley url (null)\", e);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * edit bar/trolley\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editBarTrolley(bart) {\r\n\t\t\ttry {\r\n\t\t\t\topenBarTrolleyModal(bart);\r\n\t\t\t} catch (e) {\r\n\t\t\t\tLogService.debug(\"template barTrolley url (bart)\", e);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* delete bar/trolley\r\n\t\t* @memberof ReportCtrl\r\n\t\t*/\r\n\t\tfunction deleteBarTrolley(bart) {\r\n\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this record?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\tBarTrolleyFactory.deleteFromList(bart, report.BarTrolleys);\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t}\r\n\r\n\t\t// function showOrHideBarTrolleyInputs() {\r\n\t\t// \tdebugger;\r\n\t\t// \t$scope.showBarTrolleyUploadImage = $scope.report.BarTrolleys.filter(function (arg) { return filterPhotos(arg); }).length > 0 || $scope.report.BarTrolleys.length == 0;\r\n\t\t// \t$scope.showBarTrolleyInsertData = !$scope.report.BarTrolleys.filter(function (arg) { return filterPhotos(arg); }).length > 0 || $scope.report.BarTrolleys.length == 0;\r\n\t\t// }\r\n\r\n\t\t// function filterPhotos(arg) {\r\n\t\t// \tif (arg == null) {\r\n\t\t// \t\treturn [];\r\n\t\t// \t}\r\n\t\t// \telse {\r\n\t\t// \t\treturn arg.photos;\r\n\t\t// \t}\r\n\t\t// }\r\n\r\n\t\t// CCMS \r\n\t\t/**\r\n\t\t * define open ccms crew position dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openCCMSCrewPositionModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgCrew.html',\r\n\t\t\t\tcontroller: 'CCMSCrewPositionCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tcrew: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\tif (result != null && result.Object != null) {\r\n\t\t\t\t\t\t//check if the same crew member already exists\r\n\t\t\t\t\t\tvar unique = true;\r\n\t\t\t\t\t\tvar errorField = null;\r\n\t\t\t\t\t\tif (result.Object.CrewId != null && result.Object.CrewId != '') {\r\n\t\t\t\t\t\t\tif (report.CCMSCrewPositions.filter(function (x) {\r\n\t\t\t\t\t\t\t\treturn x.CrewId == result.Object.CrewId;\r\n\t\t\t\t\t\t\t}, true).length > 0) {\r\n\t\t\t\t\t\t\t\tunique = false;\r\n\t\t\t\t\t\t\t\terrorField = \"id\";\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (result.Object.Initials != null && result.Object.Initials != '') {\r\n\t\t\t\t\t\t\tif (report.CCMSCrewPositions.filter(function (x) {\r\n\t\t\t\t\t\t\t\treturn x.Initials.toUpperCase() == result.Object.Initials.toUpperCase();\r\n\t\t\t\t\t\t\t}, true).length > 0) {\r\n\t\t\t\t\t\t\t\tunique = false;\r\n\t\t\t\t\t\t\t\terrorField = \"initials\";\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (unique) {\r\n\t\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\t\treport.CCMSCrewPositions.push(result.Object);\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t\t\t} else {\r\n\r\n\t\t\t\t\t\t\tbootbox.alert(\"

Warning

Crew member with given \" + errorField + \", already exists in this flight's crew and you may not add it again!\");\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * add new ccms crew positio\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addNewCCMSCrewPosition() {\r\n\t\t\topenCCMSCrewPositionModal(null);\r\n\t\t}\r\n\t\t//TODO REMOVE UNUSED\r\n\t\t/**\r\n\t\t * edit ccms crew position\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editCCMSCrewPosition(crew) {\r\n\t\t\topenCCMSCrewPositionModal(crew);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * delete ccms crew position\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction deleteCCMSCrewPosition(crew) {\r\n\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this record?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\tCCMSCrewPositionFactory.deleteFromList(crew, report.CCMSCrewPositions);\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t}\r\n\r\n\t\t// Grooming issue modal\r\n\t\t$scope.openGroomingForm = function (crew) {\r\n\t\t\tif (!$scope.groomingReportsByCrew) {\r\n\t\t\t\t$scope.groomingReportsByCrew = GroomingCategoriesFactory.loadGroomingReports();\r\n\t\t\t}\r\n\r\n\t\t\t // Fetch existing data or initialize default data\r\n\t\t\t var existingData = $scope.groomingReportsByCrew[crew.CrewId];\r\n\t\t\t var groomingData = existingData || groomingCategories.map(category => ({\r\n\t\t\t\t Id: category.Id,\r\n\t\t\t\t Label: category.Label,\r\n\t\t\t\t Description: category.Description,\r\n\t\t\t\t OrderNo: category.OrderNo,\r\n\t\t\t\t UserInput: '' \r\n\t\t\t }));\r\n\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgGroomingIssue.html',\r\n\t\t\t\tcontroller: 'GroomimgCategoriesModalCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tcrewData: function () {\r\n\t\t\t\t\t\treturn crew; \r\n\t\t\t\t\t},\r\n\t\t\t\t\tgroomingCategories: function () {\r\n\t\t\t\t\t\treturn groomingData; \r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}).result.then(function (result) {\r\n\t\t\t\tif (result) {\r\n\t\t\t\t // Save all categories for this crew, preserving the display of unfilled ones\r\n\t\t\t\t $scope.groomingReportsByCrew[crew.CrewId] = result;\r\n\r\n\t\t\t\t // Filter and log only completed categories\r\n\t\t\t\t var completedCategories = result.filter(category => category.UserInput && category.UserInput.trim() !== '');\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t};\r\n\r\n\t\t// Flight Detail\r\n\t\tfunction openFlightDetailModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgFlightDetail.html',\r\n\t\t\t\tcontroller: 'FlightDetailCtrl',\r\n\t\t\t\tsize: 'md',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tfd: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}).result.then(function (result) {\r\n\t\t\t\tif (result != null) {\r\n\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// First Aid Kit\r\n\t\t/**\r\n\t\t * define open first aid kit dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openFirstAidKitModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgFirstAid.html',\r\n\t\t\t\tcontroller: 'FirstAidKitCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tfak: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t},\r\n\t\t\t\t\tIsEMK: inputObject != null && inputObject.IsEMK\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\treport.FirstAidKits.push(result.Object);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * add new EMK first aid kit\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addNewEMKFirstAidKit() {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgFirstAid.html',\r\n\t\t\t\tcontroller: 'FirstAidKitCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tfak: null,\r\n\t\t\t\t\tIsEMK: true\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\treport.FirstAidKits.push(result.Object);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * add new first aid kit\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addNewFirstAidKit() {\r\n\t\t\topenFirstAidKitModal(null);\r\n\t\t}\r\n\t\t/**\r\n\t\t * edit first aid kit\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editFirstAidKit(fak) {\r\n\t\t\topenFirstAidKitModal(fak);\r\n\t\t}\r\n\t\t/**\r\n\t\t * delete first aid kit\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction deleteFirstAidKit(fak) {\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this record?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\tFirstAidKitFactory.deleteFromList(fak, report.FirstAidKits);\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t}\r\n\r\n\t\t// Medical Incidents\r\n\t\t/**\r\n\t\t * define open medical incident dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openMedicalIncidentModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgMedical.html',\r\n\t\t\t\tcontroller: 'MedicalIncidentCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tmed: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\treport.MedicalIncidents.push(result.Object);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t});\r\n\r\n\t\t\t//HACK FOR IOS:: Trying to sign, scrolls the modal dialog\r\n\t\t\t//following code, fixes that issue, but it is not a good looking solution\r\n\t\t\t$timeout(function () {\r\n\t\t\t\tif (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {\r\n\t\t\t\t\t$('.modal')\r\n\t\t\t\t\t\t.css({\r\n\t\t\t\t\t\t\tposition: 'absolute',\r\n\t\t\t\t\t\t\tmarginTop: $(window).scrollTop() + 'px',\r\n\t\t\t\t\t\t\tbottom: 'auto'\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t$('.modal-backdrop').css({\r\n\t\t\t\t\t\tposition: 'absolute',\r\n\t\t\t\t\t\ttop: 0,\r\n\t\t\t\t\t\tleft: 0,\r\n\t\t\t\t\t\twidth: '100%',\r\n\t\t\t\t\t\theight: Math.max(\r\n\t\t\t\t\t\t\tdocument.body.scrollHeight, document.documentElement.scrollHeight,\r\n\t\t\t\t\t\t\tdocument.body.offsetHeight, document.documentElement.offsetHeight,\r\n\t\t\t\t\t\t\tdocument.body.clientHeight, document.documentElement.clientHeight\r\n\t\t\t\t\t\t) + 'px'\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}, 1000, false);\r\n\t\t}\r\n\t\t/**\r\n\t\t * add new medical incident\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addNewMedicalIncident() {\r\n\t\t\topenMedicalIncidentModal(null);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * edit medical incident\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editMedicalIncident(med) {\r\n\t\t\topenMedicalIncidentModal(med);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * delete medical incident\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction deleteMedicalIncident(med) {\r\n\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this record?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\tMedicalIncidentFactory.deleteFromList(med, report.MedicalIncidents);\r\n\t\t\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t}\r\n\r\n\t\t// Special meals\r\n\t\t/**\r\n\t\t * define open special meal issue dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openSpecialMealIssueModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgSpecialMeal.html',\r\n\t\t\t\tcontroller: 'SpecialMealIssueCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tsmi: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\treport.SpecialMealIssues.push(result.Object);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * add new special meal issue\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addNewSpecialMealIssue() {\r\n\t\t\topenSpecialMealIssueModal(null);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * edit special meal issue\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editSpecialMealIssue(smi) {\r\n\t\t\topenSpecialMealIssueModal(smi);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * delete special meal issue\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction deleteSpecialMealIssue(smi) {\r\n\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this record?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\tSpecialMealIssueFactory.deleteFromList(smi, report.SpecialMealIssues);\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\r\n\t\t}\r\n\r\n\t\t// Supplies\r\n\t\t/**\r\n\t\t * define open supply dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openSupplyModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgSupply.html',\r\n\t\t\t\tcontroller: 'SupplyCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tsup: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\treport.Supplies.push(result.Object);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * add new supply\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addNewSupply() {\r\n\t\t\topenSupplyModal(null);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * edit supply\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editSupply(sup) {\r\n\t\t\topenSupplyModal(sup);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * delete supply\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction deleteSupply(sup) {\r\n\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this record?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\tSupplyFactory.deleteFromList(sup, report.Supplies);\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\r\n\t\t// Seat Upgrades\r\n\t\tcheckEligibleUpgrades();\r\n\t\t/**\r\n\t\t * define open upgrade dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction checkEligibleUpgrades() {\r\n\t\t\tvar eligiblePassengers = [];\r\n\r\n\t\t\tvar paxInfo = null;\r\n\t\t\tPaxInfoFactory.getPaxInfoFromStorage(report.FlightId, function (result) {\r\n\t\t\t\tpaxInfo = result;\r\n\r\n\t\t\t\tif (paxInfo && paxInfo.Seatmap) {\r\n\t\t\t\t\tfor (var i = 0; i < paxInfo.Seatmap.length; i++) {\r\n\t\t\t\t\t\tfor (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\r\n\t\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns[j].IsEligibleForUpgrade && paxInfo.Seatmap[i].Columns[j].Cabin == 'Y') {\r\n\t\t\t\t\t\t\t\tvar alreadyUpgraded = false;\r\n\t\t\t\t\t\t\t\tfor (var k = 0; k < report.UpgradedPassengers.length; k++) {\r\n\t\t\t\t\t\t\t\t\tif (report.UpgradedPassengers[k].UCI == paxInfo.Seatmap[i].Columns[j].UCI &&\r\n\t\t\t\t\t\t\t\t\t\treport.UpgradedPassengers[k].PNR == paxInfo.Seatmap[i].Columns[j].PNR &&\r\n\t\t\t\t\t\t\t\t\t\treport.UpgradedPassengers[k].OriginalSeatNo == paxInfo.Seatmap[i].Columns[j].SeatNo) {\r\n\t\t\t\t\t\t\t\t\t\talreadyUpgraded = true;\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\tif (!alreadyUpgraded) {\r\n\t\t\t\t\t\t\t\t\teligiblePassengers.push(paxInfo.Seatmap[i].Columns[j]);\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t$scope.eligiblePassengers = eligiblePassengers.length;\r\n\t\t\t});\r\n\t\t}\r\n\t\t/**\r\n\t\t * define open upgrade dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openUPGDModal(inputObject) {\r\n\r\n\t\t\tPaxInfoFactory.getPaxInfoFromStorage(report.FlightId, function (paxInfo) {\r\n\r\n\t\t\t\t$uibModal.open({\r\n\t\t\t\t\ttemplateUrl: 'views/Dialogs/dlgUPGD.html',\r\n\t\t\t\t\tcontroller: 'UPGDCtrl',\r\n\t\t\t\t\tsize: 'lg',\r\n\t\t\t\t\tbackdrop: 'static',\r\n\t\t\t\t\tkeyboard: false,\r\n\t\t\t\t\tresolve: {\r\n\t\t\t\t\t\tupgradedPassenger: function () {\r\n\t\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\treport: function () {\r\n\t\t\t\t\t\t\treturn report;\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\tpaxInfo: function () {\r\n\t\t\t\t\t\t\treturn paxInfo;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\t\treport.UpgradedPassengers.push(result.Object);\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tcheckEligibleUpgrades();\r\n\t\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * add new Upgrade\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addNewUPGD() {\r\n\t\t\topenUPGDModal(null);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * edit Upgrade\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editUPGD(upgradedPassenger) {\r\n\t\t\topenUPGDModal(upgradedPassenger);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * delete Upgrade\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction deleteUPGD(upgradedPassenger) {\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this record?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\treport.UpgradedPassengers = report.UpgradedPassengers.filter(function (p) {\r\n\t\t\t\t\t\t\t\treturn p.OriginalSeatNo != upgradedPassenger.OriginalSeatNo && p.UCI != upgradedPassenger.UCI;\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\tcheckEligibleUpgrades();\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// Change Seat\r\n\t\t$scope.allPassengers = 0;\r\n\t\tgetAllPasseengersCounter();\r\n\r\n\t\tfunction getAllPasseengersCounter() {\r\n\t\t\tPaxInfoFactory.getPaxInfoFromStorage(report.FlightId, function (result) {\r\n\t\t\t\tvar paxInfo = result;\r\n\t\t\t\tvar allPassengers = [];\r\n\t\t\t\tif (paxInfo) {\r\n\t\t\t\t\tfor (var i = 0; i < paxInfo.Seatmap.length; i++) {\r\n\t\t\t\t\t\tfor (var j = 0; j < paxInfo.Seatmap[i].Columns.length; j++) {\r\n\r\n\t\t\t\t\t\t\tif (paxInfo.Seatmap[i].Columns[j].SeatNo && !paxInfo.Seatmap[i].Columns[j].IsEmptySeat) {\r\n\t\t\t\t\t\t\t\tallPassengers.push(paxInfo.Seatmap[i].Columns[j]);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t$scope.allPassengers = allPassengers.length;\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * define open change seat dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openChangeSeatModal(inputObject) {\r\n\r\n\t\t\tPaxInfoFactory.getPaxInfoFromStorage(report.FlightId, function (paxInfo) {\r\n\r\n\t\t\t\t$uibModal.open({\r\n\t\t\t\t\ttemplateUrl: 'views/Dialogs/dlgSeatChange.html',\r\n\t\t\t\t\tcontroller: 'SeatChangeCtrl',\r\n\t\t\t\t\tsize: 'lg',\r\n\t\t\t\t\tbackdrop: 'static',\r\n\t\t\t\t\tkeyboard: false,\r\n\t\t\t\t\tresolve: {\r\n\t\t\t\t\t\tchangedSeat: function () {\r\n\t\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\treport: function () {\r\n\t\t\t\t\t\t\treturn report;\r\n\t\t\t\t\t\t},\r\n\t\t\t\t\t\tpaxInfo: function () {\r\n\t\t\t\t\t\t\treturn paxInfo;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t})\r\n\t\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\t\treport.ChangedSeats.push(result.Object);\r\n\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t\t});\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * add new seat change\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addNewChangedSeat() {\r\n\t\t\topenChangeSeatModal(null);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * edit changed seat\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editChangedSeat(changedSeat) {\r\n\t\t\topenChangeSeatModal(changedSeat);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * delete changed seat\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction deleteChangedSeat(changedSeat) {\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this record?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\treport.ChangedSeats = report.ChangedSeats.filter(function (p) {\r\n\t\t\t\t\t\t\t\treturn p.OriginalSeatNo != changedSeat.OriginalSeatNo && p.UCI != changedSeat.UCI;\r\n\t\t\t\t\t\t\t});\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// Travel value seal \r\n\t\t/**\r\n\t\t * define open travel value seal dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openTravelValueSealModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgTravelValueSeal.html',\r\n\t\t\t\tcontroller: 'TravelValueSealCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\ttvs: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\treport.TravelValueSeals.push(result.Object);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * add new travel value seal\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addNewTravelValueSeal() {\r\n\t\t\topenTravelValueSealModal(null);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * edit travel value seal\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editTravelValueSeal(tvs) {\r\n\t\t\topenTravelValueSealModal(tvs);\r\n\t\t}\r\n\t\t/**\r\n\t\t * delete travel value seal\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction deleteTravelValueSeal(tvs) {\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this record?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\tTravelValueSealFactory.deleteFromList(tvs, report.TravelValueSeals);\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// Incomplete In-flight Services \r\n\t\t/**\r\n\t\t * define open Incomplete In-flight Service dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openIncompleteServiceModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgIncompleteServices.html',\r\n\t\t\t\tcontroller: 'IncompleteServicesIssueCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tservice: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t},\r\n\t\t\t\t\tfleetId: function () {\r\n\t\t\t\t\t\treturn flight.Fleet.Id;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\treport.IncompleteServices.push(result.Object);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * add new travel value seal\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction addIncompleteService() {\r\n\t\t\topenIncompleteServiceModal(null);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * edit travel value seal\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editIncompleteService(service) {\r\n\t\t\topenIncompleteServiceModal(service);\r\n\t\t}\r\n\t\t/**\r\n\t\t * delete travel value seal\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction deleteIncompleteService(service) {\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this record?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\tIncompleteServicesIssueFactory.deleteFromList(service, report.IncompleteServices);\r\n\t\t\t\t\t\t\t$timeout($scope.reportItemValueChanged);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t\t\t* add new additional feedback\r\n\t\t\t\t* @memberof ReportCtrl\r\n\t\t\t\t*/\r\n\t\tfunction addAdditionalFeedback() {\r\n\t\t\topenAdditionalFeedbackModal(null);\r\n\t\t}\r\n\t\t/**\r\n\t\t * edit additional feedback\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction editAdditionalFeedback(feedback) {\r\n\t\t\topenAdditionalFeedbackModal(feedback);\r\n\t\t}\r\n\r\n\t\t// First Aid Kit\r\n\t\t/**\r\n\t\t * define open first aid kit dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openAdditionalFeedbackModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgAdditionalFeedback.html',\r\n\t\t\t\tcontroller: 'AdditionalFeedbackCtrl',\r\n\t\t\t\tsize: 'lg',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\tfeedback: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\t\t\t\t\tif (result != null) {\r\n\t\t\t\t\t\tif (result.isInsertMode) {\r\n\t\t\t\t\t\t\treport.FirstAidKits.push(result.Object);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\tangular.extend(inputObject, result.Object);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t});\r\n\t\t}\r\n\t\t//TimePicker times - convert to Date UTC\r\n\t\t$scope.BoardingDisembarkationTimes = {\r\n\t\t\tFirstPaxDisembarkationTime: $scope.report.FirstPaxDisembarkationTime ? new Date($scope.report.FirstPaxDisembarkationTime).toUTC() : null,\r\n\t\t\tLastPaxDisembarkationTime: $scope.report.LastPaxDisembarkationTime ? new Date($scope.report.LastPaxDisembarkationTime).toUTC() : null,\r\n\t\t\tFirstPaxTime: $scope.report.FirstPaxTime ? new Date($scope.report.FirstPaxTime).toUTC() : null,\r\n\t\t\tLastPaxTime: $scope.report.LastPaxTime ? new Date($scope.report.LastPaxTime).toUTC() : null,\r\n\t\t};\r\n\r\n\t\t// Boarding times\r\n\t\tvar hasFirstTime = false;\r\n\t\tvar hasLastTime = false;\r\n\t\t$scope.FirstPaxGetTimeUTC = firstPaxGetTimeUTC;\r\n\t\t$scope.LastPaxGetTimeUTC = lastPaxGetTimeUTC;\r\n\t\t$scope.firstPaxTimeChanged = firstPaxTimeChanged;\r\n\t\t$scope.lastPaxTimeChanged = lastPaxTimeChanged;\r\n\r\n\t\tfunction firstPaxTimeChanged() {\r\n\t\t\tif (!hasFirstTime) {\r\n\t\t\t\tfirstPaxGetTimeUTC();\r\n\t\t\t\thasFirstTime = true;\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t//From timepicker(date) to report(moment)\r\n\t\t\t\tvar dateObj = new Date($scope.BoardingDisembarkationTimes.FirstPaxTime).fromUTC();\r\n\t\t\t\t$scope.report.FirstPaxTime = moment(dateObj);\r\n\t\t\t}\r\n\t\t}\r\n\t\tfunction lastPaxTimeChanged() {\r\n\t\t\tif (!hasLastTime) {\r\n\t\t\t\tlastPaxGetTimeUTC();\r\n\t\t\t\thasLastTime = true;\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t//From timepicker(date) to report(moment)\r\n\t\t\t\tvar dateObj = new Date($scope.BoardingDisembarkationTimes.LastPaxTime).fromUTC();\r\n\t\t\t\t$scope.report.LastPaxTime = moment(dateObj);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction firstPaxGetTimeUTC() {\r\n\t\t\t$scope.report.FirstPaxTime = moment.utc();\r\n\r\n\t\t\t//convert to date for uib timepicker\r\n\t\t\t$scope.BoardingDisembarkationTimes.FirstPaxTime = moment($scope.report.FirstPaxTime).toDate().toUTC();\r\n\r\n\t\t\tsaveDraftClicked();\r\n\r\n\t\t}\r\n\t\tfunction lastPaxGetTimeUTC() {\r\n\t\t\t$scope.report.LastPaxTime = moment.utc();\r\n\r\n\t\t\t//convert to date for uib timepicker\r\n\t\t\t$scope.BoardingDisembarkationTimes.LastPaxTime = moment($scope.report.LastPaxTime).toDate().toUTC();\r\n\t\t\tsaveDraftClicked();\r\n\t\t}\r\n\r\n\t\t// Disembarkation times\r\n\t\tvar hasFirstDisembarkationTime = false;\r\n\t\tvar hasLastDisembarkationTime = false;\r\n\t\t$scope.FirstPaxGetDisembarkationTimeUTC = firstPaxGetDisembarkationTimeUTC;\r\n\t\t$scope.LastPaxGetDisembarkationTimeUTC = lastPaxGetDisembarkationTimeUTC;\r\n\t\t$scope.firstPaxDisembarkationTimeChanged = firstPaxDisembarkationTimeChanged;\r\n\t\t$scope.lastPaxDisembarkationTimeChanged = lastPaxDisembarkationTimeChanged;\r\n\r\n\t\tfunction firstPaxDisembarkationTimeChanged() {\r\n\t\t\tif (!hasFirstDisembarkationTime) {\r\n\t\t\t\tfirstPaxGetDisembarkationTimeUTC();\r\n\t\t\t\thasFirstDisembarkationTime = true;\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t//From timepicker(date) to report(moment)\r\n\t\t\t\tvar dateObj = new Date($scope.BoardingDisembarkationTimes.FirstPaxDisembarkationTime).fromUTC();\r\n\t\t\t\t$scope.report.FirstPaxDisembarkationTime = moment(dateObj);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction lastPaxDisembarkationTimeChanged() {\r\n\t\t\tif (!hasLastDisembarkationTime) {\r\n\t\t\t\tlastPaxGetDisembarkationTimeUTC();\r\n\t\t\t\thasLastDisembarkationTime = true;\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\t//From timepicker(date) to report(moment)\r\n\t\t\t\tvar dateObj = new Date($scope.BoardingDisembarkationTimes.LastPaxDisembarkationTime).fromUTC();\r\n\t\t\t\t$scope.report.LastPaxDisembarkationTime = moment(dateObj);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfunction firstPaxGetDisembarkationTimeUTC() {\r\n\t\t\t//apply moment time in report\r\n\t\t\t$scope.report.FirstPaxDisembarkationTime = moment.utc();\r\n\r\n\t\t\t//convert to date for uib timepicker\r\n\t\t\t$scope.BoardingDisembarkationTimes.FirstPaxDisembarkationTime = moment($scope.report.FirstPaxDisembarkationTime).toDate().toUTC();\r\n\r\n\t\t\tsaveDraftClicked();\r\n\r\n\t\t}\r\n\t\tfunction lastPaxGetDisembarkationTimeUTC() {\r\n\t\t\t$scope.report.LastPaxDisembarkationTime = moment.utc();\r\n\r\n\t\t\t//convert to date for uib timepicker\r\n\t\t\t$scope.BoardingDisembarkationTimes.LastPaxDisembarkationTime = moment($scope.report.LastPaxDisembarkationTime).toDate().toUTC();\r\n\r\n\t\t\tsaveDraftClicked();\r\n\t\t}\r\n\r\n\r\n\t\t//Item Photos\r\n\r\n\t\t/**\r\n\t\t * define open item photos dialog function\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction openItemPhotosModal(inputObject) {\r\n\t\t\t$uibModal.open({\r\n\t\t\t\ttemplateUrl: 'views/Dialogs/dlgItemPhotos.html',\r\n\t\t\t\tcontroller: 'ItemPhotosCtrl',\r\n\t\t\t\tsize: 'md',\r\n\t\t\t\tbackdrop: 'static',\r\n\t\t\t\tkeyboard: false,\r\n\t\t\t\tresolve: {\r\n\t\t\t\t\titem: function () {\r\n\t\t\t\t\t\treturn inputObject;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t})\r\n\t\t\t\t.result.then(function (result) {\r\n\r\n\t\t\t\t\t$scope.reportItemValueChanged();\r\n\t\t\t\t});\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * attach Photo On Various Item\r\n\t\t * @memberof ReportCtrl\r\n\t\t */\r\n\t\tfunction attachPhotoOnVariousItem(item) {\r\n\t\t\topenItemPhotosModal(item);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* attach Photo On Various Item\r\n\t\t* @memberof ReportCtrl\r\n\t\t*/\r\n\t\tfunction attachPhotoOnBarTrolley(item) {\r\n\r\n\t\t\tif (item == undefined) {\r\n\t\t\t\tvar x = BarTrolleyFactory.createNew();\r\n\t\t\t\titem = x;\r\n\t\t\t\treport.BarTrolleys.push(item);\r\n\t\t\t}\r\n\t\t\topenItemPhotosModal(item);\r\n\t\t}\r\n\r\n\t\t$scope.autoAdjustTarget = null;\r\n\t\t$scope.autoAdjustTimer = null;\r\n\t\t$scope.autoAdjustElement = function (element) {\r\n\t\t\tif (element) {\r\n\t\t\t\tautoAdjustTextarea(element);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t$scope.autoAdjustRun = function () {\r\n\t\t\tvar t = $scope.autoAdjustTarget;\r\n\t\t\t$scope.autoAdjustElement(t);\r\n\t\t\t$scope.autoAdjustTarget = null;\r\n\t\t\t$scope.autoAdjustTimer = null;\r\n\r\n\t\t\t// also, update the report and save it to a temp place\r\n\t\t\treport.updateTotals();\r\n\t\t\tif (report.Status != 'synched')\r\n\t\t\t\treport.saveReportAsTemp();\r\n\t\t}\r\n\r\n\t\t$scope.adjustTextarea = function ($event) {\r\n\t\t\t// $event.keyCode = 13\r\n\t\t\t// performing adjusts using a timer, to minimize times it executes, and\r\n\t\t\t// make it faster on ipad2\r\n\t\t\tif ($scope.autoAdjustTimer != null) {\r\n\t\t\t\tclearTimeout($scope.autoAdjustTimer);\r\n\t\t\t\t// old object pending... execute its adjustment and then plan new\r\n\t\t\t\t// object's adjustment\r\n\t\t\t\tif ($event.target != $scope.autoAdjustTarget) {\r\n\t\t\t\t\t$scope.autoAdjustRun();\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t$scope.autoAdjustTarget = $event.target;\r\n\t\t\t$scope.autoAdjustTimer = setTimeout($scope.autoAdjustRun, 500);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t* It handles the cabin report when u want to navigate to another view\r\n\t\t* @memberof CabinReports\r\n\t\t* @param {Object} report input the cabin report \r\n\t\t*/\r\n\t\tfunction handleIfReport(report) {\r\n\t\t\tif ($scope.state == 'report') {\r\n\t\t\t\tif (report == null) {\r\n\t\t\t\t\treport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(report.FlightId);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// delete the temp report\r\n\t\t\t\tCabinReportLocalEditFactory.deleteTempReport();\r\n\r\n\t\t\t\t//reuse guid if this was a new report\r\n\t\t\t\tif (report.Status == 'pending')\r\n\t\t\t\t\tReportGuidFactory.restoreGuid(report.ReportGuid);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t$scope.BarSealsImage = [];\r\n\t\t$scope.BarSealsImageRemarks;\r\n\t}\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('ReportsHistoryCtrl', ReportsHistoryCtrl);\r\n\r\n\r\n function ReportsHistoryCtrl($scope, $routeParams, $timeout, ReportsHistoryFactory, FlightFactory) {\r\n var reportId = $routeParams.reportId;\r\n var flightId = $routeParams.flightId;\r\n var reportType = $routeParams.reportType;\r\n var flight = FlightFactory.getFlightFromStorage(flightId);\r\n\r\n window.addEventListener('online', function (e) { $timeout(checkConnectionStatus()); });\r\n\r\n $scope.reports = [];\r\n $scope.flight = flight;\r\n $scope.contentToShow = \"loading\";\r\n $scope.errorMessage = \"\";\r\n $scope.showImage = showImage;\r\n $scope.imageData = \"\";\r\n $scope.closeImage = closeImage;\r\n\r\n $scope.init = function () {\r\n checkConnectionStatus();\r\n }\r\n $scope.init();\r\n\r\n /**\r\n * Fetches the reports\r\n * @memberof ReportsHistoryCtrl \r\n */\r\n function fetchReports() {\r\n ReportsHistoryFactory.getReportsHistory(reportId,reportType)\r\n .then(response => handleResponse(response))\r\n .catch(function () { showError(\"We could not get any reports!\"); });\r\n }\r\n\r\n /**\r\n * Displays the error message\r\n * @memberof ReportsHistoryCtrl \r\n * @param {string} message message to display\r\n */\r\n function showError(message) {\r\n $scope.contentToShow = \"error\";\r\n $scope.errorMessage = message;\r\n }\r\n\r\n /**\r\n * Checks if the client is online or offline \r\n * if is online fetches the reports else displays relative message\r\n * @memberof ReportsHistoryCtrl \r\n */\r\n function checkConnectionStatus() {\r\n var isOnline = window.navigator.onLine;\r\n if (isOnline) {\r\n fetchReports()\r\n }\r\n else {\r\n showError(\"Please check the internet connection!\");\r\n }\r\n }\r\n\r\n /**\r\n * Handles the response from the API \r\n * if is success displays the reports else shows the error message.\r\n * @memberof ReportsHistoryCtrl \r\n * @param {object} response the response object from API\r\n */\r\n function handleResponse(response) {\r\n if (response.data.success) {\r\n if (response.data.data.length > 0) {\r\n $scope.contentToShow = \"reports\";\r\n $scope.reports = response.data.data;\r\n }\r\n else {\r\n showError(\"There are no reports for this flight!\");\r\n }\r\n }\r\n else {\r\n showError(\"We could not get any reports!\");\r\n }\r\n }\r\n\r\n /**\r\n * Displays the image in full screen\r\n * @memberof ReportsHistoryCtrl \r\n * @param {object} ImageData The\r\n */\r\n function showImage(ImageData) {\r\n $scope.contentToShow = \"image\";\r\n $scope.imageData = ImageData;\r\n }\r\n\r\n /**\r\n * The function that closes the image and displays the reports again\r\n * @memberof ReportsHistoryCtrl \r\n */\r\n function closeImage() {\r\n $scope.contentToShow = \"reports\";\r\n }\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('ReportsHistoryFactory', ReportsHistoryFactory)\r\n\r\n /* @ngInject */\r\n function ReportsHistoryFactory($http, apiUrl) {\r\n\r\n /**\r\n * Fetches the ReportIncidents from API\r\n * @memberof ReportsHisReportsHistoryFactorytoryCtrl \r\n */\r\n function getReportsHistory(reportId, reportType) {\r\n return $http.get(apiUrl + '/reports/GetHistoryReport?reportId=' + reportId + '&type=' + reportType, { 'Content-Type': 'application/json' })\r\n .then(x => { return x });\r\n }\r\n\r\n var service = {\r\n getReportsHistory: getReportsHistory,\r\n }\r\n return service;\r\n }\r\n\r\n})(); ","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('RequestFactory', RequestFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name RequestFactory\r\n * @description \r\n * Add & delete requests and get Roster Requests & get ancillaries\r\n * @ngInject\r\n */\r\n function RequestFactory($http, apiUrl, GenericService) {\r\n /**\r\n * Initialize the CrewAssessment\r\n * @memberof AssessmentSyncResultFactory\r\n */\r\n function RequestSubmissionDeadline() {\r\n this.showSubmissionDeadlineModal = false;\r\n }\r\n\r\n var submitResponseObj = { success: false, message: '', data: null };\r\n var objType = 'requestSubmissionEndDates'\r\n var objCallback = RequestSubmissionDeadline;\r\n\r\n var service =\r\n {\r\n setSubmissionDeadlineDateToStorage: setSubmissionDeadlineDateToStorage,\r\n getSubmissionDeadlineDateFromStorage: getSubmissionDeadlineDateFromStorage,\r\n showSubmissionDeadlineModal: showSubmissionDeadlineModal,\r\n showSubmissionDeadlineAlert: showSubmissionDeadlineAlert,\r\n updateShowSubmissionDeadlineModal: updateShowSubmissionDeadlineModal,\r\n getActiveRequests: getActiveRequests,\r\n getAncillaries: getAncillaries,\r\n sendFlightRequest: sendFlightRequest,\r\n sendShiftRequest: sendShiftRequest,\r\n sendOvernightRequest: sendOvernightRequest,\r\n sendOtherRequest: sendOtherRequest,\r\n sendGroundRequest: sendGroundRequest,\r\n deleteFlightRequest: deleteFlightRequest,\r\n deleteShiftRequest: deleteShiftRequest,\r\n deleteOvernightRequest: deleteOvernightRequest,\r\n deleteOtherRequest: deleteOtherRequest,\r\n deleteGroundRequest: deleteGroundRequest,\r\n getPastRequests: getPastRequests\r\n };\r\n\r\n /**\r\n * Save submission end date of crew member's qualification group to storage\r\n * @param {array} objList A list of Crew Expiries\r\n */\r\n function setSubmissionDeadlineDateToStorage(objList) {\r\n if (objList != null) {\r\n var submissionDeadline = { submissionEndDate: objList, showSubmissionDeadlineModal: true };\r\n GenericService.saveOne(submissionDeadline, objType, objCallback);\r\n }\r\n }\r\n\r\n /**\r\n * Calculates days left\r\n * @memberof CalendarCtrl\r\n * @return {string} usage\r\n */\r\n function daysDiff(date) {\r\n var today = moment().startOf('day');\r\n var expiryDate = moment(date);\r\n\r\n return expiryDate.diff(today, 'days');\r\n }\r\n\r\n /**\r\n * Get submission end date of crew member's qualification group from storage\r\n */\r\n function getSubmissionDeadlineDateFromStorage() {\r\n return GenericService.getOne(objType, objCallback);\r\n }\r\n\r\n /**\r\n * Shows submission deadline modal\r\n * @memberof ExpiriesFactory\r\n * @returns {bool} returns the value of showSubmissionDeadlineModal property\r\n */\r\n function showSubmissionDeadlineModal() {\r\n var needsReminder = false;\r\n var submissionDeadline = getSubmissionDeadlineDateFromStorage();\r\n if(submissionDeadline){\r\n var diffDays = daysDiff(submissionDeadline.submissionEndDate);\r\n\r\n if (submissionDeadline && submissionDeadline.submissionEndDate && submissionDeadline.showSubmissionDeadlineModal) {\r\n if (diffDays == 1 || diffDays == -1) {\r\n needsReminder = true;\r\n }\r\n }\r\n }\r\n\r\n return needsReminder;\r\n }\r\n\r\n /**\r\n * Shows submission deadline alert\r\n * @memberof ExpiriesFactory\r\n * @returns {bool} returns the value of showSubmissionDeadlineAlert property\r\n */\r\n function showSubmissionDeadlineAlert() {\r\n var needsAlert = false;\r\n var submissionDeadline = getSubmissionDeadlineDateFromStorage();\r\n if(submissionDeadline){\r\n var diffDays = daysDiff(submissionDeadline.submissionEndDate);\r\n \r\n if (submissionDeadline && submissionDeadline.submissionEndDate) {\r\n if (diffDays <= 10 && diffDays >=0) {\r\n needsAlert = true;\r\n }\r\n }\r\n }\r\n\r\n return needsAlert;\r\n }\r\n\r\n /* Update submissionEndDate modal object to storage\r\n * @memberof RequestFactory\r\n * @param {bool} canShowModal whether the modal can be displayed\r\n */\r\n function updateShowSubmissionDeadlineModal(canShowModal) {\r\n var submissionDeadline = getSubmissionDeadlineDateFromStorage();\r\n submissionDeadline.showSubmissionDeadlineModal = canShowModal;\r\n GenericService.saveOne(submissionDeadline, objType, objCallback);\r\n }\r\n\r\n /**\r\n * Gets all types of the existing requests\r\n */\r\n function getActiveRequests() {\r\n return $http.get(apiUrl + '/RosterRequests/GetRequests', { 'Content-Type': 'application/json' })\r\n .then(res => getResponse(res))\r\n .catch(res => getResponseFailed(res));;\r\n }\r\n\r\n /**\r\n * Gets all ancilleries\r\n */\r\n function getAncillaries() {\r\n return $http.get(apiUrl + '/RosterRequests/GetAncillaries', { 'Content-Type': 'application/json' })\r\n .then(res => getResponse(res))\r\n .catch(res => getResponseFailed(res));\r\n }\r\n\r\n /**\r\n * Sends the flight request\r\n */\r\n function sendFlightRequest(rosterRequest) {\r\n var requestTimesFixed = { ...rosterRequest };\r\n if(rosterRequest.afterTime){\r\n requestTimesFixed.afterTime = rosterRequest.afterTime.clone();\r\n var startDateObj = new Date(requestTimesFixed.afterTime).fromUTC();\r\n requestTimesFixed.afterTime = moment(startDateObj);\r\n }else{\r\n requestTimesFixed.afterTime = null;\r\n }\r\n if(rosterRequest.beforeTime){\r\n requestTimesFixed.beforeTime = rosterRequest.beforeTime.clone();\r\n var endDateObj = new Date(requestTimesFixed.beforeTime).fromUTC();\r\n requestTimesFixed.beforeTime = moment(endDateObj);\r\n }else{\r\n requestTimesFixed.beforeTime = null;\r\n }\r\n\r\n var rosterRequestsURL = apiUrl + '/RosterRequests/FlightRequestInsert';\r\n return $http.post(rosterRequestsURL, requestTimesFixed, { 'Content-Type': 'application/json' })\r\n .then(res => getCreateRequestResponse(res))\r\n .catch(res => getResponseFailed(res));\r\n }\r\n\r\n /**\r\n * Sends the shift request\r\n */\r\n function sendShiftRequest(rosterRequest) {\r\n var rosterRequestsURL = apiUrl + '/RosterRequests/ShiftTimeRequestInsert';\r\n return $http.post(rosterRequestsURL, rosterRequest, { 'Content-Type': 'application/json' })\r\n .then(res => getCreateRequestResponse(res))\r\n .catch(res => getResponseFailed(res));\r\n }\r\n\r\n /**\r\n * Sends the overnight request\r\n */\r\n function sendOvernightRequest(rosterRequest) {\r\n var rosterRequestsURL = apiUrl + '/RosterRequests/OvernightsRequestInsert';\r\n return $http.post(rosterRequestsURL, rosterRequest, { 'Content-Type': 'application/json' })\r\n .then(res => getCreateRequestResponse(res))\r\n .catch(res => getResponseFailed(res));\r\n }\r\n\r\n /**\r\n * Sends the other request\r\n */\r\n function sendOtherRequest(rosterRequest) {\r\n var rosterRequestsURL = apiUrl + '/RosterRequests/OtherRequestInsert';\r\n return $http.post(rosterRequestsURL, rosterRequest, { 'Content-Type': 'application/json' })\r\n .then(res => getCreateRequestResponse(res))\r\n .catch(res => getResponseFailed(res));\r\n }\r\n\r\n /**\r\n * Sends the ground request\r\n */\r\n function sendGroundRequest(rosterRequest) {\r\n var rosterRequestsURL = apiUrl + '/RosterRequests/GroundDutyRequestInsert';\r\n return $http.post(rosterRequestsURL, rosterRequest, { 'Content-Type': 'application/json' })\r\n .then(res => getCreateRequestResponse(res))\r\n .catch(res => getResponseFailed(res));\r\n }\r\n\r\n /**\r\n * Gets the response message\r\n */\r\n function getResponse(res) {\r\n submitResponseObj.success = res.data.success;\r\n if (res.data.success) {\r\n submitResponseObj.message = \"Data retrieved successfully\";\r\n submitResponseObj.data = res.data.data;\r\n }\r\n else {\r\n submitResponseObj.message = res.data.errorMessage;\r\n }\r\n return submitResponseObj;\r\n }\r\n\r\n /**\r\n * Gets the creation response message\r\n */\r\n function getCreateRequestResponse(res) {\r\n submitResponseObj.success = res.data.success;\r\n if (res.data.success) {\r\n submitResponseObj.message = \"Request submited successfully\";\r\n submitResponseObj.data = res.data.data;\r\n }\r\n else {\r\n submitResponseObj.message = res.data.errorMessage;\r\n }\r\n return submitResponseObj;\r\n }\r\n\r\n /**\r\n * Gets the response failure message\r\n */\r\n function getResponseFailed(res) {\r\n submitResponseObj.success = false;\r\n submitResponseObj.message = \"Something went wrong!\"\r\n return submitResponseObj;\r\n }\r\n\r\n /**\r\n * Deletes the flight request\r\n */\r\n function deleteFlightRequest(requestId) {\r\n var deleteRequestsURL = apiUrl + '/RosterRequests/FlightRequestDelete';\r\n return $http.post(deleteRequestsURL, requestId, { 'Content-Type': 'application/json' })\r\n .then(res => getCreateRequestResponse(res));\r\n }\r\n\r\n /**\r\n * Deletes the shift request\r\n */\r\n function deleteShiftRequest(requestId) {\r\n var deleteRequestsURL = apiUrl + '/RosterRequests/ShiftTimeRequestDelete';\r\n return $http.post(deleteRequestsURL, requestId, { 'Content-Type': 'application/json' })\r\n .then(res => getCreateRequestResponse(res));\r\n }\r\n\r\n /**\r\n * Deletes the overnight request\r\n */\r\n function deleteOvernightRequest(requestId) {\r\n var deleteRequestsURL = apiUrl + '/RosterRequests/OvernightsRequestDelete';\r\n return $http.post(deleteRequestsURL, requestId, { 'Content-Type': 'application/json' })\r\n .then(res => getCreateRequestResponse(res));\r\n }\r\n\r\n /**\r\n * Deletes the other request\r\n */\r\n function deleteOtherRequest(requestId) {\r\n var deleteRequestsURL = apiUrl + '/RosterRequests/OtherRequestDelete';\r\n return $http.post(deleteRequestsURL, requestId, { 'Content-Type': 'application/json' })\r\n .then(res => getCreateRequestResponse(res));\r\n }\r\n\r\n /**\r\n * Deletes the ground request\r\n */\r\n function deleteGroundRequest(requestId) {\r\n var deleteRequestsURL = apiUrl + '/RosterRequests/GroundDutyRequestDelete';\r\n return $http.post(deleteRequestsURL, requestId, { 'Content-Type': 'application/json' })\r\n .then(res => getCreateRequestResponse(res));\r\n }\r\n\r\n /**\r\n * Gets all types of the past requests\r\n */\r\n function getPastRequests() { \r\n return $http.get(apiUrl + '/RosterRequests/GetPastRequests', { 'Content-Type': 'application/json' })\r\n .then(res => getResponse(res))\r\n .catch(res => getResponseFailed(res));;\r\n }\r\n\r\n return service;\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('requestForm', requestForm);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name requestForm\r\n * @restrict E\r\n * @description\r\n * Crew Table with a double row per crew member\r\n * @example\r\n * Usage:\r\n * \r\n * \r\n * @ngInject\r\n */\r\n function requestForm() {\r\n function link(scope, attrs) {\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/RosterRequests/requestForm.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\n a3_cabin_reports.controller('RequestInstructionsCtrl',RequestInstructionsCtrl);\r\n\r\n /**\r\n * @memberof PilotReports\r\n * @ngdoc controller\r\n * @name RequestInstructionsCtrl\r\n * @description \r\n * Get the Roster Request Instructions\r\n * @ngInject\r\n */\r\nfunction RequestInstructionsCtrl($scope, $uibModalInstance){\r\n\t\t$scope.page = 1;\r\n\t\t$scope.cancel = cancel;\r\n $scope.nextPage = nextPage;\r\n $scope.previousPage = previousPage;\r\n \r\n $scope.instructionPages = 1;\r\n \r\n /**\r\n * Goes to the next page of leave instructions\r\n * @memberof RequestInstructionsCtrl\r\n */\r\n function nextPage(){\r\n $scope.page = $scope.page + 1;\r\n normalizePage();\r\n }\r\n \r\n /**\r\n * Goes to the previous page of leave instructions\r\n * @memberof RequestInstructionsCtrl\r\n */\r\n function previousPage(){\r\n $scope.page = $scope.page - 1;\r\n normalizePage();\r\n }\r\n \r\n /**\r\n * Normalize the page number if it is out of range\r\n * @memberof RequestInstructionsCtrl\r\n */\r\n function normalizePage(){\r\n if($scope.page > $scope.instructionPages || $scope.page<1){\r\n $scope.page = 1;\r\n }\r\n }\r\n /**\r\n * Close the modal\r\n * @memberof RequestInstructionsCtrl\r\n */\r\n\t\tfunction cancel() {\r\n\t\t\t$uibModalInstance.close('close');\r\n\t\t};\r\n\t\t\r\n\t}\r\n })(); ","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('requestItem', requestItem);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name requestItem\r\n * @restrict E\r\n * @description\r\n * Request info\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function requestItem($uibModal, RequestFactory) {\r\n function link(scope,element, attrs) {\r\n //scope.request\r\n scope.loading = false;\r\n scope.errorMessage = null;\r\n scope.contents = {\r\n showPendingIcon: false, \r\n //sholwAcknowledgedIcon: false,\r\n showAcceptedIcon: false,\r\n showRejectedIcon: false,\r\n showFullRequestComment: false,\r\n showFullRejectComment: false,\r\n rejectReason: \"\",\r\n infoMessage: \"\",\r\n loading: false,\r\n showErrorMessage: false,\r\n errorMessage: \"\" ,\r\n textclass:\"\"\r\n };\r\n \r\n scope.confirmCancelRequest =confirmCancelRequest;\r\n scope.toggleFullCommentVisibility = toggleFullCommentVisibility;\r\n scope.toggleFullRejectCommentVisibility = toggleFullRejectCommentVisibility;\r\n scope.todayDate = moment().format('DD/MM');\r\n\r\n getFlightDescription();\r\n\r\n function getFlightDescription(){\r\n scope.request.FlightDescription = null;\r\n if(scope.request.FlightNo){\r\n scope.request.FlightDescription = scope.request.FlightNo;\r\n }else if(scope.request.FlightDutyCategory){\r\n scope.request.FlightDescription = scope.request.FlightDutyCategory;\r\n }else if(scope.request.AfterTime && scope.request.BeforeTime){\r\n scope.request.FlightDescription = moment.utc(scope.request.AfterTime).format('HH:mm') + \" - \" + moment.utc(scope.request.BeforeTime).format('HH:mm'); \r\n }else if(scope.request.AfterTime){\r\n scope.request.FlightDescription = \"after \" + moment.utc(scope.request.AfterTime).format('HH:mm');\r\n }else if(scope.request.BeforeTime){\r\n scope.request.FlightDescription = \"till \" + moment.utc(scope.request.BeforeTime).format('HH:mm');\r\n }\r\n\r\n }\r\n\r\n //Toggles comments\r\n function toggleFullCommentVisibility(){\r\n scope.contents.showFullRequestComment = !scope.contents.showFullRequestComment;\r\n }\r\n function toggleFullRejectCommentVisibility(){\r\n scope.contents.showFullRejectComment = !scope.contents.showFullRejectComment;\r\n }\r\n\r\n\r\n getContents();\r\n\r\n\r\n //update contents obj:\r\n function getContents(){\r\n if (scope.request.StatusText == \"FinalAccepted\" ){\r\n scope.contents.textclass = \"text-green\";\r\n scope.contents.showAcceptedIcon = true;\r\n scope.contents.infoMessage=\"your request has been accepted!\";\r\n\r\n } else if (scope.request.StatusText == \"Accepted\"){\r\n scope.contents.textclass = \"text-indigo\";\r\n scope.contents.showPendingIcon = true;\r\n scope.contents.infoMessage =\"your request is under review!\";\r\n } else if (scope.request.StatusText == \"Pending\"){\r\n scope.contents.textclass = \"text-light-blue\";\r\n scope.contents.showPendingIcon = true;\r\n scope.contents.infoMessage =\"your request is pending!\";\r\n\r\n }else if (scope.request.StatusText == \"Acknowledged\"){\r\n scope.contents.textclass = \"text-light-blue\";\r\n scope.contents.showPendingIcon = true;\r\n scope.contents.infoMessage=\"your request is under review!\";\r\n \r\n }else if (scope.request.StatusText == \"Rejected\"){\r\n scope.contents.rejectReason = scope.rejectReason;\r\n scope.contents.textclass = \"text-red\";\r\n scope.contents.showRejectedIcon = true;\r\n scope.contents.infoMessage=\"your request has been rejected!\";\r\n }\r\n }\r\n\r\n /**\r\n * Opens confirmation modal for the request cancel action\r\n * @memberof request\r\n */\r\n function confirmCancelRequest() {\r\n bootbox.dialog({\r\n message: \"You are about to cancel your request. Are you sure?

\",\r\n title: \"Caution!\",\r\n buttons: {\r\n confirm:{\r\n label: 'Confirm',\r\n className: \"btn-danger\",\r\n callback: function(){\r\n cancelRequest();\r\n }\r\n }, \r\n cancel:{\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function(){}\r\n }\r\n }\r\n })\r\n }\r\n\r\n function cancelRequest(){\r\n scope.contents.loading = true;\r\n if(scope.requestType == \"Flight\"){\r\n RequestFactory.deleteFlightRequest(scope.request.Id).then(function (res) {\r\n handleDeleteResponse(res);\r\n }).catch(function(){\r\n handleErrorResponse();\r\n });\r\n }\r\n else if(scope.requestType == \"Ground\"){\r\n RequestFactory.deleteGroundRequest(scope.request.Id).then(function (res) {\r\n handleDeleteResponse(res);\r\n }).catch(function(){\r\n handleErrorResponse();\r\n });\r\n }\r\n else if(scope.requestType == \"ShiftTime\"){\r\n RequestFactory.deleteShiftRequest(scope.request.Id).then(function (res) {\r\n handleDeleteResponse(res);\r\n }).catch(function(){\r\n handleErrorResponse();\r\n });\r\n }\r\n else if(scope.requestType == \"Overnight\"){\r\n RequestFactory.deleteOvernightRequest(scope.request.Id).then(function (res) {\r\n handleDeleteResponse(res);\r\n }).catch(function(){\r\n handleErrorResponse();\r\n });\r\n }\r\n else if(scope.requestType == \"Other\"){\r\n RequestFactory.deleteOtherRequest(scope.request.Id).then(function (res) {\r\n handleDeleteResponse(res);\r\n }).catch(function(){\r\n handleErrorResponse();\r\n });\r\n }\r\n }\r\n\r\n function handleDeleteResponse(res){\r\n scope.contents.loading = false;\r\n if(res.success == true){ \r\n scope.refreshRequests();\r\n\r\n }else{\r\n scope.contents.showErrorMessage = true;\r\n scope.contents.errorMessage = \"Cancel request failed.\"\r\n }\r\n }\r\n function handleErrorResponse(){\r\n scope.contents.loading = false;\r\n scope.contents.showErrorMessage = true;\r\n scope.contents.errorMessage = \"Cancel request failed.\"\r\n\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/RosterRequests/requestItem.tpl.html',\r\n scope : {\r\n request: '=',\r\n requestType: \"@\",\r\n rejectReason: \"@\",\r\n refreshRequests: \"&\",\r\n isHistoryView: '@'\r\n },\r\n link: link\r\n }\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('RequestsCtrl', RequestsCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name RequestsCtrl\r\n * @description \r\n * Shows Roster Requests\r\n * @ngInject\r\n */\r\n function RequestsCtrl($scope, RequestFactory, $timeout, $uibModal, LogService) {\r\n\r\n $scope.state = 'requests';\r\n\r\n $scope.ancillaries = null;\r\n $scope.activeRequests = null;\r\n $scope.isAvailableFeature = false;\r\n $scope.hasAncillaries = false; //for testing true || live false !;\r\n $scope.showActiveRequests = false; //for testing true || live false !;\r\n $scope.contentToShow = \"loading\";\r\n window.addEventListener('online', function (e) { $timeout(checkConnectionStatus()); });\r\n $scope.init = checkConnectionStatus();\r\n $scope.closeAlert = closeAlert;\r\n $scope.openRequest = openRequest;\r\n $scope.page = null;\r\n $scope.closeForm = closeForm;\r\n $scope.newForm = {};\r\n $scope.submitRequest = submitRequest;\r\n $scope.submitForcedRequest = submitForcedRequest;\r\n $scope.forceSubmitRequest = forceSubmitRequest;\r\n $scope.getActiveRequests = getActiveRequests;\r\n $scope.updateFromValue = updateFromValue;\r\n $scope.dutyCode = \"\";\r\n $scope.showHelp = showHelp;\r\n $scope.instruction = '';\r\n $scope.flightRequestType = null;\r\n $scope.setFlightRequestType = setFlightRequestType;\r\n $scope.resetStart = resetStart;\r\n $scope.resetEnd = resetEnd;\r\n //ground duties request types:\r\n $scope.singleDayRequestType = true;\r\n $scope.toggleGroundRequestType = toggleGroundRequestType;\r\n $scope.updateFromValueGD = updateFromValueGD;\r\n $scope.submitLoader = false;\r\n\r\n $scope.toggleViewMode = toggleViewMode;\r\n $scope.getPastRequests = getPastRequests;\r\n\r\n $scope.isHistoryView = false;\r\n $scope.showPastRequests = false;\r\n $scope.hasDutyPreferencesSettings = false;\r\n\r\n //------------ Request List --------------\r\n // $scope.showMobileRequestListCriteria = true;\r\n $scope.filterRequest = filterRequest;\r\n $scope.getRequestBorderStyle = getRequestBorderStyle;\r\n $scope.getRejectReason = getRejectReason;\r\n $scope.toggle = {\r\n Accepted: true,\r\n Rejected: true,\r\n Pending: true,\r\n FinalAccepted: true\r\n }\r\n\r\n $scope.submissionDeadline = RequestFactory.getSubmissionDeadlineDateFromStorage();\r\n $scope.daysDiff = daysDiff;\r\n\r\n /**\r\n * Calculates days left\r\n * @memberof CalendarCtrl\r\n * @return {string} usage\r\n */\r\n function daysDiff(date) {\r\n var today = moment().startOf('day');\r\n var expiryDate = moment(date);\r\n\r\n return expiryDate.diff(today, 'days');\r\n }\r\n\r\n /**\r\n * Get ancillaries for the forms\r\n * @memberof RequestsCtrl \r\n */\r\n function getAncillaries() {\r\n RequestFactory.getAncillaries()\r\n .then(response => {\r\n $scope.contentToShow = \"\";\r\n if (response.success) {\r\n if (response.data) {\r\n $scope.ancillaries = response.data;\r\n\r\n // Request types based on crew member's qualification group(s) settings\r\n $scope.hasDutyPreferencesSettings = $scope.ancillaries.ShiftTimeRequests && $scope.ancillaries.ShiftTimeRequests.length > 0;\r\n $scope.hasOtherRequestsSettings = $scope.ancillaries.HasOtherRequestsSettings;\r\n $scope.hasFlightRequestsByFlightNoSettings = $scope.ancillaries.HasFlightRequestsByFlightNoSettings;\r\n $scope.hasFlightRequestsByTimeRangesSettings = $scope.ancillaries.HasFlightRequestsByTimeRangesSettings;\r\n\r\n $scope.flightOrDutyPreferenceIsVisible = ($scope.ancillaries.FlightDutyCategories && $scope.ancillaries.FlightDutyCategories.length > 0) \r\n || $scope.hasFlightRequestsByFlightNoSettings\r\n || $scope.hasFlightRequestsByTimeRangesSettings;\r\n\r\n // Create Your Request Menu: visibility option \r\n $scope.isAvailableFeature = $scope.ancillaries.DutyCodes && $scope.ancillaries.DutyCodes.length > 0 \r\n || $scope.flightOrDutyPreferenceIsVisible \r\n || $scope.hasDutyPreferencesSettings \r\n || $scope.hasOtherRequestsSettings;\r\n \r\n $scope.hasAncillaries = true;\r\n\r\n $scope.newForm.singleDate = $scope.ancillaries.RosterPeriodFrom;\r\n $scope.newForm.dateFrom = $scope.ancillaries.RosterPeriodFrom;\r\n $scope.newForm.dateTo = $scope.ancillaries.RosterPeriodTo;\r\n\r\n //groundDuties\r\n $scope.newForm.dutyDateFrom = $scope.ancillaries.RosterPeriodFrom;\r\n $scope.newForm.dutyDateTo = $scope.ancillaries.RosterPeriodFrom;\r\n\r\n $scope.optionsSingle = {\r\n minDate: $scope.ancillaries.RosterPeriodFrom,\r\n initDate: $scope.ancillaries.RosterPeriodFrom\r\n }\r\n $scope.optionsFrom = {\r\n minDate: $scope.ancillaries.RosterPeriodFrom,\r\n initDate: $scope.ancillaries.RosterPeriodFrom\r\n }\r\n $scope.optionsTo = {\r\n minDate: $scope.ancillaries.RosterPeriodFrom,\r\n initDate: $scope.ancillaries.RosterPeriodTo\r\n }\r\n $scope.optionsDutyDateTo = {\r\n minDate: $scope.ancillaries.RosterPeriodFrom,\r\n initDate: $scope.ancillaries.RosterPeriodFrom\r\n }\r\n \r\n // Fetch flight category types for the dropdown list\r\n $scope.ancillaries.flightCategoryTypes = []; \r\n\r\n if($scope.hasFlightRequestsByFlightNoSettings) {\r\n $scope.ancillaries.flightCategoryTypes.push({Value: 1, Text:'Flight No.'});\r\n }\r\n\r\n if($scope.ancillaries.FlightDutyCategories && $scope.ancillaries.FlightDutyCategories.length > 0) {\r\n $scope.ancillaries.flightCategoryTypes.push({Value: 2, Text:'Flight Duty Preference'});\r\n }\r\n \r\n if($scope.hasFlightRequestsByTimeRangesSettings) {\r\n $scope.ancillaries.flightCategoryTypes.push({Value: 3, Text:'Flight Duty Preference with time limit'});\r\n }\r\n }\r\n else {\r\n //TODO:: fix message\r\n showError(\"Ancillaries not found.\");\r\n }\r\n }\r\n else {\r\n showError(response.message);\r\n }\r\n\r\n })\r\n }\r\n\r\n /**\r\n * Get Active Requests\r\n * @memberof RequestsCtrl \r\n */\r\n function getActiveRequests() {\r\n RequestFactory.getActiveRequests()\r\n .then(response => {\r\n if (response.success) {\r\n if (response.data) {\r\n $scope.activeRequests = response.data;\r\n $scope.instruction = response.data.QualificationGroupInstruction;\r\n $scope.showActiveRequests = response.data.FlightRequests.length || response.data.GroundDutyRequests.length || response.data.OtherRequests.length ||\r\n response.data.OvernightsRequests.length || response.data.ShiftTimeRequests.length;\r\n } else {\r\n showError(\"Something went wrong while fetching your roster requests.\");\r\n }\r\n }\r\n else {\r\n showError(response.message);\r\n }\r\n\r\n });\r\n }\r\n\r\n function getPastRequests() {\r\n RequestFactory.getPastRequests()\r\n .then(response => {\r\n if (response.success) {\r\n if (response.data) {\r\n $scope.pastRequests = response.data;\r\n $scope.isHistoryView = true;\r\n $scope.instruction = response.data.QualificationGroupInstruction;\r\n $scope.showPastRequests = response.data.FlightRequests.length > 0 || response.data.GroundDutyRequests.length > 0|| response.data.OtherRequests.length > 0||\r\n response.data.OvernightsRequests.length >0 || response.data.ShiftTimeRequests.length > 0; \r\n } else {\r\n showError(\"Something went wrong while fetching your roster requests.\");\r\n }\r\n }\r\n else {\r\n showError(response.message);\r\n }\r\n\r\n });\r\n }\r\n\r\n /**\r\n * Displays the error message\r\n * @memberof RequestsCtrl \r\n * @param {string} message message to display\r\n */\r\n function showError(message) {\r\n $scope.contentToShow = \"error\";\r\n $scope.errorMessage = message;\r\n }\r\n\r\n /**\r\n * Displays the success message\r\n * @memberof RequestsCtrl\r\n */\r\n function showSuccess(message) {\r\n $scope.contentToShow = \"success\";\r\n $scope.successMessage = message;\r\n }\r\n\r\n function closeAlert() {\r\n $scope.contentToShow = \"\";\r\n }\r\n\r\n\r\n /**\r\n * Checks if the client is online or offline \r\n * @memberof RequestsCtrl \r\n */\r\n function checkConnectionStatus() {\r\n var isOnline = window.navigator.onLine;\r\n if (isOnline) {\r\n getAncillaries();\r\n getActiveRequests();\r\n }\r\n else {\r\n showError(\"Please check your internet connection!\");\r\n }\r\n }\r\n\r\n /**\r\n * Date to always greater than date from\r\n * @memberof RequestsCtrl \r\n */\r\n function updateFromValue(dateFrom) {\r\n $scope.newForm.dateTo = dateFrom;\r\n $scope.optionsTo = {\r\n minDate: dateFrom\r\n }\r\n }\r\n\r\n /**\r\n * Date picker limits for the ground duty requests\r\n * @memberof RequestsCtrl \r\n */\r\n function updateFromValueGD(dateFrom, limitation) {\r\n $scope.newForm.dateTo = dateFrom;\r\n\r\n $scope.optionsDutyDateTo = {\r\n initDate: dateFrom,\r\n minDate: dateFrom,\r\n maxDate: dateFrom.AddDays(limitation - 1)\r\n }\r\n }\r\n\r\n function setFlightRequestType(){\r\n //[{Value: 1, Text:'Flight No.'}, {Value: 2, Text:'Flight Duty Preference'}, {Value: 3, Text:'Time Limitations'}]\r\n //$scope.flightRequestType = parseInt($scope.newForm.flightRequestType, 10);\r\n if ($scope.newForm.flightRequestType != null) {\r\n $scope.flightRequestType = parseInt($scope.newForm.flightRequestType, 10);\r\n } else {\r\n $scope.flightRequestType = null; \r\n }\r\n }\r\n \r\n function resetStart(){\r\n\t\t\t$scope.newForm.afterTime = null;\r\n\t\t}\r\n\t\tfunction resetEnd(){\r\n\t\t\t$scope.newForm.beforeTime = null;\r\n\t\t}\r\n\r\n\r\n function toggleGroundRequestType(){\r\n if($scope.newForm.groundRequestType == 'continuous'){\r\n $scope.singleDayRequestType = false;\r\n }else{\r\n $scope.singleDayRequestType = true;\r\n }\r\n }\r\n\r\n /**\r\n * Opens the request type selected\r\n * @memberof RequestsCtrl\r\n */\r\n function openRequest(inputObject, dutyCode) {\r\n clearForms();\r\n if (inputObject == \"Flight\") {\r\n $scope.page = 'Flight';\r\n }\r\n else if (inputObject == \"Duty Preference\") {\r\n $scope.page = 'Duty Preference';\r\n }\r\n else if (inputObject == \"Overnight\") {\r\n $scope.page = 'Overnight'\r\n }\r\n else if (inputObject == \"Other\") {\r\n $scope.page = 'Other';\r\n }\r\n else if (inputObject == \"Ground Duty\") {\r\n $scope.page = 'Ground Duty';\r\n $scope.dutyCode = dutyCode;\r\n }\r\n }\r\n\r\n /**\r\n * Submits the request form\r\n * @memberof RequestsCtrl\r\n */\r\n function submitRequest(inputObject, dutyCode) {\r\n $scope.submitLoader = true;\r\n if (inputObject == \"Flight\" && $scope.flightRequestType != null) {\r\n var rosterRequest = {\r\n FlightDate: $scope.newForm.singleDate.toString(\"yyyy/MM/dd\"),\r\n ReasonId: $scope.newForm.requestReason.Id,\r\n Comments: $scope.newForm.comments,\r\n Type: $scope.flightRequestType,\r\n IsForced: false\r\n };\r\n if($scope.flightRequestType == 1){\r\n rosterRequest.FlightNo = $scope.newForm.flightNo;\r\n }else if($scope.flightRequestType == 2){\r\n rosterRequest.FlightDutyCategoryId = $scope.newForm.flightDuty.Id;\r\n }\r\n else if($scope.flightRequestType == 3){\r\n rosterRequest.afterTime = ($scope.newForm.afterTime !== null && $scope.newForm.afterTime !== undefined) ? moment($scope.newForm.afterTime) : null;\r\n rosterRequest.beforeTime = ($scope.newForm.beforeTime !== null && $scope.newForm.beforeTime !== undefined) ? moment($scope.newForm.beforeTime) : null;\r\n }\r\n RequestFactory.sendFlightRequest(rosterRequest)\r\n .then(response => {\r\n handleSubmitResponse(response, rosterRequest);\r\n });\r\n }\r\n else if (inputObject == \"Ground Duty\") {\r\n \r\n //validation with duty limitation\r\n var trimmedFrom = new Date($scope.newForm.dateFrom);\r\n var trimmedTo = new Date($scope.newForm.dateTo);\r\n var diffDays = Date.DifferenceInDays(trimmedFrom.trimTime(), trimmedTo.trimTime());\r\n if(diffDays > dutyCode.Limitation ){\r\n //show warning message? : \r\n $scope.disableSubmit = true;\r\n }\r\n\r\n if($scope.singleDayRequestType){\r\n $scope.newForm.dateTo = $scope.newForm.dateFrom;\r\n }\r\n\r\n var rosterRequest = {\r\n DutyDateFrom: $scope.newForm.dateFrom.toString(\"yyyy/MM/dd\"),\r\n DutyDateTo: $scope.newForm.dateTo.toString(\"yyyy/MM/dd\"),\r\n GroundDuty: dutyCode.Code,\r\n ReasonId: $scope.newForm.requestReason.Id,\r\n Comments: $scope.newForm.comments,\r\n IsForced: false\r\n };\r\n\r\n RequestFactory.sendGroundRequest(rosterRequest)\r\n .then(response => {\r\n handleSubmitResponse(response, rosterRequest);\r\n });\r\n }\r\n else if (inputObject == \"Duty Preference\") {\r\n var rosterRequest = {\r\n DateFrom: $scope.newForm.dateFrom.toString(\"yyyy/MM/dd\"),\r\n DateTo: $scope.newForm.dateTo.toString(\"yyyy/MM/dd\"),\r\n ShiftTimeId: $scope.newForm.shiftTime.Id,\r\n ReasonId: $scope.newForm.requestReason.Id,\r\n Comments: $scope.newForm.comments\r\n };\r\n RequestFactory.sendShiftRequest(rosterRequest)\r\n .then(response => {\r\n handleSubmitResponse(response);\r\n });\r\n }\r\n else if (inputObject == \"Overnight\") {\r\n var rosterRequest = {\r\n DateFrom: $scope.newForm.dateFrom.toString(\"yyyy/MM/dd\"),\r\n DateTo: $scope.newForm.dateTo.toString(\"yyyy/MM/dd\"),\r\n Minimum: $scope.newForm.minOvernight,\r\n Maximum: $scope.newForm.maxOvernight,\r\n ReasonId: $scope.newForm.requestReason.Id,\r\n Comments: $scope.newForm.comments\r\n };\r\n RequestFactory.sendOvernightRequest(rosterRequest)\r\n .then(response => {\r\n handleSubmitResponse(response);\r\n });\r\n }\r\n else if (inputObject == \"Other\") {\r\n var rosterRequest = {\r\n DateFrom: $scope.newForm.dateFrom.toString(\"yyyy/MM/dd\"),\r\n DateTo: $scope.newForm.dateTo.toString(\"yyyy/MM/dd\"),\r\n ReasonId: $scope.newForm.requestReason.Id,\r\n RequestFreeText: $scope.newForm.otherComments\r\n };\r\n RequestFactory.sendOtherRequest(rosterRequest)\r\n .then(response => {\r\n handleSubmitResponse(response);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Handles the response from the API\r\n * @memberof RequestsCtrl \r\n * @param {object} response the response object from API\r\n */\r\n function handleSubmitResponse(response, rosterRequest) {\r\n var responseData = null;\r\n\r\n if (response.data ) {\r\n if (typeof response.data === 'string') {\r\n try {\r\n responseData = JSON.parse(response.data);\r\n } catch (error) {\r\n LogService.error(error, 'Failed to parse JSON');\r\n }\r\n } else {\r\n responseData = response.data;\r\n }\r\n }\r\n \r\n\r\n if (rosterRequest && response.success == true && responseData && responseData.success == false) {\r\n if(responseData.isOverlappingDuty){\r\n //bootbox for the overlap warning\r\n showOverlappingMessage();\r\n }else if(responseData.periodNotFound){\r\n showPeriodNotFoundMessage();\r\n }else if($scope.page == \"Ground Duty\" || $scope.page == \"Flight\"){\r\n //bootbox to confirm the forced submit - new submit on confirmed\r\n forceSubmitRequest(rosterRequest, $scope.page, responseData);\r\n }\r\n else{\r\n //show error message\r\n showError('Request submission failed.');\r\n }\r\n } else if (response.success == false) {\r\n //show error message\r\n showError(response.message);\r\n } else if ( responseData.success == false) {\r\n //show error message\r\n showError('Request submission failed.');\r\n } else {\r\n //show success message\r\n showSuccess(\"Request submited successfully.\");\r\n //refresh request list!\r\n getActiveRequests();\r\n }\r\n closeForm();\r\n\r\n }\r\n\r\n /**\r\n * Clears forms\r\n * @memberof RequestsCtrl\r\n */\r\n function clearForms() {\r\n $scope.newForm = {};\r\n if ($scope.ancillaries) {\r\n $scope.newForm.singleDate = $scope.ancillaries.RosterPeriodFrom;\r\n $scope.newForm.dateFrom = $scope.ancillaries.RosterPeriodFrom;\r\n $scope.newForm.dateTo = $scope.ancillaries.RosterPeriodTo;\r\n $scope.singleDayRequestType = true;\r\n $scope.submitLoader = false;\r\n $scope.disableSubmit = false;\r\n }\r\n }\r\n\r\n /**\r\n * Closes forms\r\n * @memberof RequestsCtrl\r\n */\r\n function closeForm() {\r\n clearForms();\r\n $scope.page = null;\r\n }\r\n\r\n\r\n /**\r\n * Opens confirmation modal when request is submitted\r\n * @memberof RequestsCtrl\r\n */\r\n function forceSubmitRequest(rosterRequest, type, responseData) {\r\n\r\n var rosterPeriodFrom = moment.utc(responseData.rosterPeriodFrom).format('D MMM YYYY');\r\n var rosterPeriodTo = moment.utc(responseData.rosterPeriodTo).format('D MMM YYYY');\r\n var title = \"Warning!\";\r\n console.log(rosterRequest);\r\n var message = \"\";\r\n if(responseData.limitationReached ){\r\n message = message + \"You have exceeded the maximum number of Requests \" + \r\n \"(\" + responseData.activeRequests + \"/\" + responseData.maxLimit + \")\" + \" for this Roster Period \" +\r\n \"(\" + rosterPeriodFrom + \" to \" + rosterPeriodTo + \").\" + \"
\";\r\n }\r\n if(responseData.isOverdue == true){\r\n message = message + \"The Deadline to submit requests for this Roster Period \" + \"(\" + rosterPeriodFrom + \" to \" + rosterPeriodTo + \") has passed.

\";\r\n }\r\n\r\n if(type == \"Ground Duty\" && responseData.hasDailyLimitation == true){\r\n message = message + \"The selected date \" + rosterRequest.DutyDate + \" has limited Availability. The probability to get your request is low.
\";\r\n }\r\n if(type == \"Ground Duty\" && responseData.weekendRequestsLimitReached == true ){\r\n message = message + \"You have exceeded the allowed number of Weekends Requests for this Roster Period \" +\r\n \"(\" + rosterPeriodFrom + \" to \" + rosterPeriodTo + \").

\";\r\n }\r\n message = message + \" Your request will be ignored by the system. Do you want to send it for Managment Approval?
\";\r\n\r\n bootbox.dialog({\r\n message: message,\r\n title: title,\r\n buttons: {\r\n confirm: {\r\n label: 'Confirm',\r\n className: \"btn-success\",\r\n callback: function () {\r\n submitForcedRequest(rosterRequest, type);\r\n }\r\n },\r\n cancel: {\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function () { }\r\n }\r\n }\r\n })\r\n }\r\n\r\n /**\r\n * Opens a modal with overlapping message\r\n * @memberof RequestsCtrl\r\n */\r\n function showOverlappingMessage(){\r\n var title = \"Warning!\";\r\n var message = \"You cannot submit 2 requests for the same date.
\";\r\n bootbox.dialog({\r\n message: message,\r\n title: title,\r\n buttons: {\r\n cancel: {\r\n label: \"Close\",\r\n className: \"btn-default\",\r\n callback: function () { }\r\n }\r\n }\r\n })\r\n }\r\n /**\r\n * Opens a modal with overlapping message\r\n * @memberof RequestsCtrl\r\n */\r\n function showPeriodNotFoundMessage(){\r\n var title = \"Warning!\";\r\n var message = \"You cannot send request for this roster period.
\";\r\n bootbox.dialog({\r\n message: message,\r\n title: title,\r\n buttons: {\r\n cancel: {\r\n label: \"Close\",\r\n className: \"btn-default\",\r\n callback: function () { }\r\n }\r\n }\r\n })\r\n }\r\n \r\n /**\r\n * Submits the forced request\r\n * @memberof RequestsCtrl\r\n */\r\n function submitForcedRequest(rosterRequest, type) {\r\n \r\n if (type == \"Flight\") {\r\n rosterRequest.IsForced = true;\r\n RequestFactory.sendFlightRequest(rosterRequest)\r\n .then(response => {\r\n handleSubmitResponse(response);\r\n });\r\n }\r\n else if (type == \"Ground Duty\") {\r\n rosterRequest.IsForced = true;\r\n\r\n RequestFactory.sendGroundRequest(rosterRequest)\r\n .then(response => {\r\n handleSubmitResponse(response);\r\n });\r\n }\r\n }\r\n\r\n function getRejectReason(rejectReasonId) {\r\n var reasonText = \"\";\r\n if(rejectReasonId && $scope.ancillaries ){\r\n var rejectReason = $scope.ancillaries.RejectReasons.find(f => f.Id == rejectReasonId)\r\n if (rejectReason) {\r\n reasonText = rejectReason.Text;\r\n }\r\n }\r\n return reasonText;\r\n }\r\n\r\n function filterRequest(request) {\r\n var isShown = false;\r\n if (request.Id > 0) {\r\n if (( request.StatusText == \"FinalAccepted\") && $scope.toggle.FinalAccepted) {\r\n isShown = true;\r\n } else if (((request.ValidationStatusText == \"Validated\" && request.StatusText != \"FinalAccepted\") || request.StatusText == \"Accepted\" || request.StatusText == \"Acknowledged\") && $scope.toggle.Accepted) {\r\n isShown = true;\r\n } else if ((request.StatusText == \"Pending\") && $scope.toggle.Pending) {\r\n isShown = true;\r\n } else if (request.StatusText == \"Rejected\" && $scope.toggle.Rejected) {\r\n isShown = true;\r\n } \r\n }\r\n return isShown;\r\n }\r\n\r\n function getRequestBorderStyle(request) {\r\n var textclass = \"\";\r\n if (request.StatusText == \"FinalAccepted\") {\r\n textclass = \"border-left-green\";\r\n } else if (request.StatusText == \"Accepted\") {\r\n textclass = \"border-left-indigo\";\r\n } else if (request.StatusText == \"Pending\" || request.StatusText == \"Acknowledged\") {\r\n textclass = \"border-left-light-blue\";\r\n } else if (request.StatusText == \"Rejected\") {\r\n textclass = \"border-left-red\";\r\n } else {\r\n textclass = \"border-left-blue-gray\";\r\n }\r\n return textclass;\r\n }\r\n\r\n\r\n\r\n function showHelp() {\r\n $uibModal.open({\r\n templateUrl: 'views/RosterRequests/dlgRequestInstructions.html',\r\n controller: 'RequestInstructionsCtrl',\r\n size: 'lg',\r\n scope: $scope,\r\n backdrop: 'static',\r\n keyboard: false,\r\n resolve: {}\r\n })\r\n }\r\n\r\n function toggleViewMode(elem, className) {\r\n $('body').find('div#' + elem + ' > div').not('.tip').hide(\"slow\");\r\n $('body').find('div#' + elem + ' div.' + className).not('.tip').show(\"slow\");\r\n }\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('FatigueCtrl', FatigueCtrl);\r\n\r\n function FatigueCtrl($scope, $routeParams, FlightFactory, $location, SafetyReportFactory, $timeout) {\r\n var flightId = $routeParams.flightId;\r\n var flight = FlightFactory.getFlightFromStorage(flightId);\r\n\r\n $scope.flight = flight;\r\n $scope.responseMessage = \"\";\r\n $scope.showPanel = \"submit\";\r\n\r\n $scope.operationalPhasesOptions = [\r\n 'Parked', \r\n 'Pushback', \r\n 'Taxi-Out',\r\n 'Take-Off',\r\n 'Climb',\r\n 'Cruise',\r\n 'Descent',\r\n 'Approach',\r\n 'Landing', \r\n 'Taxi-In',\r\n ]\r\n\r\n $scope.rateFeltOptions = [\r\n 'Fully Alert - wide awake',\r\n 'Very Lively - responsive, but not at peak',\r\n 'OK - somewhat fresh',\r\n 'A Little Tired - less than fresh',\r\n 'Moderately Tired - let down'\r\n ]\r\n\r\n $scope.signsPhysicalOptions = [\r\n 'No physical signs noted ', 'Fidgeting', 'Rubbing eyes', 'Heavy eyelids', 'Yawning', 'Frequent blinking', 'Staring blankly', \r\n 'Long blinks', 'Difficulty keeping eyes open', 'Head nodding', 'Micro-sleeps', 'Unintentional sleeps'\r\n ]\r\n\r\n $scope.signsCognitiveOptions = [\r\n 'No cognitive signs noted', 'Impaired attention', 'Difficulty concentrating', 'Impaired memory', 'Reduced communication', 'Impaired problem solving', \r\n 'Increased risk taking', 'Impaired situational awareness', 'Accidentally doing the wrong thing (error)', 'Accidentally not doing the right thing (omission)', \r\n 'Failure to anticipate the event or action'\r\n ]\r\n\r\n $scope.signsEmotionalOptions = [\r\n 'No emotional signs', 'More quiet or withdrawn than usual', 'Lacking in energy', 'Lacking in motivation to do the task well', 'Negative mood', \r\n 'Irritable or grumpy behavior'\r\n ]\r\n\r\n $scope.counterMeasuresOptions = [\r\n 'Controlled rest', 'Caffeine', 'Use of automationy', 'Change of controls', 'Turn up the lights', \r\n 'Food, drink', 'Increased checks', 'Workload share', 'Increased communication', 'Inform a colleague'\r\n ]\r\n\r\n $scope.hours24Options = Array.from({ length: 21 }, (_, i) => i); // Generates an array with values from 0 to 20\r\n\r\n $scope.hoursAwakeOptions = Array.from({ length: 21 }, (_, i) => i); // Generates an array with values from 0 to 20\r\n\r\n $scope.formData = {\r\n flightId: $routeParams.flightId,\r\n flightNo: flight.FlightNo,\r\n flightDate: flight.ScheduledDeparture,\r\n flightDep: flight.Departure,\r\n flightArr: flight.Arrival,\r\n flightRegistration: flight.AcTailNo,\r\n occurenceTitle: \"\",\r\n description: \"\",\r\n // attachedFiles: [],\r\n operationalPhase: \"\",\r\n rateFelt: \"\",\r\n signsPhysical: [],\r\n signsCognitive: [],\r\n signsEmotional: [],\r\n hours24: \"\",\r\n hoursAwake: \"\",\r\n rateFeltSecond: \"\",\r\n counterMeasures: []\r\n };\r\n\r\n $scope.toggleSelection = function(option, signs) {\r\n var idx = signs.indexOf(option);\r\n if (idx > -1) {\r\n signs.splice(idx, 1);\r\n } else {\r\n signs.push(option);\r\n }\r\n };\r\n \r\n $scope.isChecked = function(option, signs) {\r\n return signs.indexOf(option) > -1;\r\n };\r\n \r\n $scope.getSelectedOptionsText = function(signs) {\r\n if (signs.length === 0) {\r\n return \"- Select options -\";\r\n }\r\n return signs.join(', ');\r\n };\r\n\r\n $scope.isRequiredFieldEmpty = function(field) {\r\n return !field.length;\r\n };\r\n\r\n $scope.sizeLimitKb = 25000;\r\n $scope.fileTooLargeMsg = false;\r\n $scope.confirmCreateFatigueReport = confirmCreateFatigueReport;\r\n $scope.fileUploaded = fileUploaded;\r\n $scope.removeFile = removeFile;\r\n $scope.isIFileTooLarge = isFileTooLarge;\r\n $scope.submitFatigueReport = submitFatigueReport;\r\n $scope.sendFatigueReport = sendFatigueReport;\r\n $scope.submitted = false;\r\n\r\n\r\n function gotoFlightInfo(flightId) {\r\n $location.path('/flightinfo/' + flightId);\r\n }\r\n\r\n function submitFatigueReport() {\r\n if ($scope.fatigueReport.$valid) {\r\n confirmCreateFatigueReport();\r\n } else {\r\n bootbox.alert(\"Please fill in all the required fields.\");\r\n }\r\n }\r\n\r\n function confirmCreateFatigueReport() {\r\n bootbox.dialog({\r\n message: \"Would you like to proceed with the Fatigue Report?

\",\r\n title: \"Send Report\",\r\n buttons: {\r\n confirm: {\r\n label: 'Confirm',\r\n className: \"btn-success\",\r\n callback: function () {\r\n $scope.showPanel = \"loading\";\r\n SafetyReportFactory.saveFatigueReport($scope.formData)\r\n .then(res => handleSubmitResponse(res));\r\n }\r\n },\r\n cancel: {\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function () { }\r\n }\r\n }\r\n })\r\n }\r\n \r\n function handleSubmitResponse(res) {\r\n var alertStyle = res.success ? \"success\" : \"warning\";\r\n \r\n bootbox.dialog({\r\n message: \"
\" + res.message + \"
\",\r\n title: \"Response Message\",\r\n buttons: {\r\n cancel:{\r\n label: \"Close\",\r\n className: \"btn-default\",\r\n callback: function(){\r\n if (res.success) {\r\n $timeout(gotoFlightInfo(flightId));\r\n }\r\n else {\r\n $timeout($scope.showPanel = \"submit\"); \r\n }\r\n }\r\n } \r\n }\r\n }) \r\n }\r\n \r\n function sendFatigueReport(formData) {\r\n $scope.submitted = true;\r\n if ($scope.fatigueReport.$valid && !$scope.isRequiredFieldEmpty(formData.signsPhysical) && !$scope.isRequiredFieldEmpty(formData.signsCognitive) && !$scope.isRequiredFieldEmpty(formData.signsEmotional)) {\r\n createFatigueReport();\r\n } else {\r\n bootbox.alert(\"Please fill in all the required fields.\");\r\n }\r\n }\r\n function createFatigueReport() {\r\n bootbox.dialog({\r\n message: \"Would you like to send the Fatigue Report?

\",\r\n title: \"Send Report\",\r\n buttons: {\r\n confirm: {\r\n label: 'Confirm',\r\n className: \"btn-success\",\r\n callback: function () {\r\n $scope.showPanel = \"loading\";\r\n SafetyReportFactory.emailFatigueReport($scope.formData)\r\n .then(res => handleSubmitResponse(res));\r\n }\r\n },\r\n cancel: {\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function () { }\r\n }\r\n }\r\n })\r\n }\r\n \r\n function isFileTooLarge(image) {\r\n var isLarge= false;\r\n if (image && image.dataURL != null) {\r\n isLarge = (image.dataURL.length > $scope.sizeLimitKb * 1024);\r\n }\r\n return isLarge;\r\n }\r\n \r\n function fileUploaded(data) {\r\n var fileResult = data; //$scope.imageBrowsed;\r\n var uploadedFile = {};\r\n\r\n uploadedFile.fileBlobb = fileResult.dataURL;\r\n uploadedFile.description = fileResult.fileType || fileResult.file.type;\r\n uploadedFile.fileName = fileResult.fileName;\r\n\r\n // var files = $scope.formData.attachedFiles;\r\n if ($scope.formData.attachedFiles.length < 5) {\r\n // var n = Object.create(attachedFile);\r\n $scope.formData.attachedFiles.push(uploadedFile);\r\n\r\n } else {\r\n $scope.showMaxFiles = true;\r\n }\r\n }\r\n\r\n function removeFile(attachedFile) {\r\n var files = $scope.formData.attachedFiles;\r\n var arrayLenght = files.length;\r\n var itemIndex = -1;\r\n for (var i = 0; i < arrayLenght; i++) {\r\n if (files[i].fileName == attachedFile.fileName) {\r\n itemIndex = i;\r\n break;\r\n }\r\n }\r\n\r\n if (itemIndex >= 0) {\r\n files.splice(itemIndex, 1);\r\n\r\n return attachedFile;\r\n }\r\n if ($scope.showMaxImages) {\r\n appendPhoto();\r\n }\r\n $scope.showMaxImages = false;\r\n }\r\n\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.controller('SafetyCtrl', SafetyCtrl);\r\n\r\nfunction SafetyCtrl($scope,operationalPhases,$timeout, $routeParams, FlightFactory, $location, SafetyReportFactory){\r\n var flightId = $routeParams.flightId;\r\n var flight = FlightFactory.getFlightFromStorage(flightId);\r\n\r\n $scope.flight = flight;\r\n $scope.operationalPhases = angular.fromJson(operationalPhases);\r\n\r\n $scope.responseMessage = \"\";\r\n $scope.showPanel = \"submit\";\r\n\r\n $scope.formData = {\r\n flightId: $routeParams.flightId,\r\n flightNo: flight.FlightNo,\r\n flightDate: flight.ScheduledDeparture,\r\n flightDep:flight.Departure,\r\n flightArr: flight.Arrival,\r\n flightRegistration: flight.AcTailNo,\r\n occurenceTitle: \"\",\r\n description: \"\",\r\n selectedPhase: \"\",\r\n attachedFiles: [],\r\n isConfidential: false\r\n };\r\n $scope.sizeLimitKb = 25000;\r\n $scope.fileTooLargeMsg = false;\r\n $scope.fileUploaded = fileUploaded;\r\n $scope.removeFile = removeFile;\r\n $scope.isIFileTooLarge = isFileTooLarge;\r\n $scope.submitForm = submitForm;\r\n\r\n\r\n\r\n function gotoFlightInfo(flightId){\r\n $location.path('/flightinfo/' + flightId);\r\n }\r\n\r\n function submitForm() {\r\n if ($scope.formCabinReport.$valid) {\r\n confirmCreateReport(); \r\n //console.log($scope.formData.attachedFiles); \r\n }else {\r\n bootbox.alert(\"Please fill in all the required fields.\");\r\n }\r\n }\r\n\r\n function confirmCreateReport() {\r\n bootbox.dialog({\r\n message: \"Would you like to proceed with the Safety Report?

\",\r\n title: \"Send Report\",\r\n buttons: {\r\n confirm:{\r\n label: 'Confirm',\r\n className: \"btn-success\",\r\n callback: function(){\r\n $scope.showPanel = \"loading\";\r\n SafetyReportFactory.saveSafetyReport($scope.formData)\r\n .then(res => handleSubmitResponse(res));\r\n }\r\n }, \r\n cancel:{\r\n label: \"Cancel\",\r\n className: \"btn-default\",\r\n callback: function(){}\r\n }\r\n }\r\n })\r\n } \r\n\r\n function handleSubmitResponse(res) {\r\n var alertStyle = res.success ? \"success\" : \"warning\";\r\n\r\n bootbox.dialog({\r\n message: \"
\" + res.message + \"
\",\r\n title: \"Response Message\",\r\n buttons: {\r\n cancel:{\r\n label: \"Close\",\r\n className: \"btn-default\",\r\n callback: function(){\r\n if (res.success) {\r\n $timeout(gotoFlightInfo(flightId));\r\n }\r\n else {\r\n $timeout($scope.showPanel = \"submit\");\r\n }\r\n }\r\n } \r\n }\r\n })\r\n \r\n }\r\n\r\n function isFileTooLarge(image) {\r\n var isLarge= false;\r\n if (image && image.dataURL != null) {\r\n isLarge = (image.dataURL.length > $scope.sizeLimitKb * 1024);\r\n }\r\n return isLarge;\r\n }\r\n\r\n function fileUploaded(data) {\r\n var fileResult = data; //$scope.imageBrowsed;\r\n var uploadedFile = {};\r\n\r\n\r\n if (isFileTooLarge(data)) {\r\n $scope.fileTooLargeMsg = true;\r\n } else {\r\n $scope.fileTooLargeMsg = false;\r\n uploadedFile.fileBlobb = fileResult.dataURL;\r\n uploadedFile.description = fileResult.fileType || fileResult.file.type;\r\n uploadedFile.fileName = fileResult.fileName;\r\n\r\n // var files = $scope.formData.attachedFiles;\r\n if ($scope.formData.attachedFiles.length < 5) {\r\n // var n = Object.create(attachedFile);\r\n $scope.formData.attachedFiles.push(uploadedFile);\r\n\r\n } else {\r\n $scope.showMaxFiles = true;\r\n }\r\n }\r\n }\r\n\r\n function removeFile(attachedFile){\r\n var files = $scope.formData.attachedFiles;\r\n var arrayLenght = files.length;\r\n var itemIndex = -1;\r\n for (var i = 0; i < arrayLenght; i++) {\r\n if (files[i].fileName == attachedFile.fileName) {\r\n itemIndex = i;\r\n break;\r\n }\r\n }\r\n \r\n if (itemIndex >= 0) {\r\n files.splice(itemIndex, 1);\r\n\r\n return attachedFile;\r\n }\r\n if($scope.showMaxImages){\r\n appendPhoto();\r\n }\r\n $scope.showMaxImages = false;\r\n }\r\n \r\n}\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('SafetyReportFactory', SafetyReportFactory);\r\n\r\n function SafetyReportFactory($http, apiUrl) {\r\n\r\n var submitResponseObj = { success: false, message: '' };\r\n\r\n var service = {\r\n saveSafetyReport: saveSafetyReport,\r\n saveFatigueReport: saveFatigueReport,\r\n emailFatigueReport: emailFatigueReport\r\n };\r\n\r\n function saveSafetyReport(safetyReport) {\r\n var aqdBaseURL = apiUrl + '/SafetyReports/SaveSafetyReport';\r\n return $http.post(aqdBaseURL, safetyReport, { 'Content-Type': 'application/json' })\r\n .then (res => getResponse(res))\r\n .catch(res => getResponseFailed(res));\r\n }\r\n\r\n function saveFatigueReport(fatigueReport) {\r\n var aqdBaseURL = apiUrl + '/SafetyReports/SaveFatigueReport';\r\n\r\n return $http.post(aqdBaseURL, fatigueReport, { 'Content-Type': 'application/json' })\r\n .then (res => getFatigueResponse(res))\r\n .catch(res => getResponseFailed(res));\r\n }\r\n\r\n function getResponse(res) {\r\n submitResponseObj.success = res.data.success;\r\n if (res.data.success) {\r\n submitResponseObj.message = \"Safety Report Submited successfully\";\r\n }\r\n else {\r\n submitResponseObj.message = res.data.errorMessage;\r\n }\r\n return submitResponseObj;\r\n }\r\n\r\n function getResponseFailed(res) {\r\n submitResponseObj.success = false;\r\n submitResponseObj.message = \"Something went wrong!\"\r\n return submitResponseObj;\r\n }\r\n\r\n function emailFatigueReport(fatigueReport) {\r\n var aqdBaseURL = apiUrl + '/SafetyReports/EmailFatigueReport';\r\n\r\n return $http.post(aqdBaseURL, fatigueReport, { 'Content-Type': 'application/json' })\r\n .then(res => getFatigueResponse(res))\r\n .catch(res => getFatigueResponseFailed(res));\r\n }\r\n\r\n function getFatigueResponse(res) {\r\n submitResponseObj.success = res.data.success;\r\n if (res.data.success) {\r\n submitResponseObj.message = \"Fatigue Report sent successfully.\";\r\n }\r\n else {\r\n submitResponseObj.message = res.data.errorMessage;\r\n }\r\n return submitResponseObj;\r\n }\r\n\r\n function getFatigueResponseFailed(res) {\r\n submitResponseObj.success = false;\r\n submitResponseObj.message = \"Something went wrong!\"\r\n return submitResponseObj;\r\n }\r\n\r\n return service;\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('AcknowledgeModalCtrl', AcknowledgeModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name AcknowledgeModalCtrl\r\n * @description \r\n * Warning Modal about unread mandatory memos\r\n * @ngInject\r\n */\r\n function AcknowledgeModalCtrl($scope, ScheduleAcknowledgeFactory, $route, $uibModalInstance) {\r\n\r\n $scope.ConfirmAcknowledge = ConfirmAcknowledge;\r\n $scope.cancel = cancel;\r\n $scope.showContent = 'confirm';\r\n $scope.responseObj = { success: false, message: '', Results: [] };\r\n $scope.results = [];\r\n\r\n function ConfirmAcknowledge(){\r\n $scope.showContent = 'loading';\r\n ScheduleAcknowledgeFactory.acknowledgeChanges()\r\n .then(res => handleSubmitResponse(res))\r\n .catch(res => handleSubmitResponse(res));\r\n \r\n }\r\n\r\n function handleSubmitResponse(res) {\r\n $scope.showContent = 'results';\r\n $scope.responseObj = res;\r\n }\r\n\r\n /**\r\n * Closes modal\r\n * @memberof ProposalInfoModalCtr\r\n */\r\n function cancel() {\r\n $uibModalInstance.close('cancel');\r\n\r\n if($scope.responseObj.success){\r\n $route.reload();\r\n }\r\n \r\n }\r\n }\r\n\r\n \r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('ScheduleAcknowledgeFactory', ScheduleAcknowledgeFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ScheduleAcknowledgeFactory\r\n * @description \r\n * Get list, Update list & Acknowledge schedule changes\r\n * @ngInject\r\n */\r\n function ScheduleAcknowledgeFactory(localStorageMD5Service, GenericService, $http, apiUrl, defaultCalendarDate) {\r\n\r\n /**\r\n * Initialize the ScheduleChanges\r\n * @memberof ScheduleAcknowledgeFactory\r\n */\r\n function ScheduleChanges() {\r\n this.dates = [];\r\n this.showScheduleChangesModal = false;\r\n }\r\n\r\n var objType = 'ScheduleChanges';\r\n var objCallback = ScheduleChanges;\r\n\r\n var response = {\r\n success: false,\r\n message: '',\r\n Results: []\r\n };\r\n\r\n var service = {\r\n setAllScheduleChangesToStorage: setAllScheduleChangesToStorage,\r\n getScheduleChangesFromStorage: getScheduleChangesFromStorage,\r\n updateShowScheduleChangesModal: updateShowScheduleChangesModal,\r\n showScheduleChangesModal: showScheduleChangesModal,\r\n hasScheduleChanges: hasScheduleChanges,\r\n acknowledgeChanges: acknowledgeChanges\r\n };\r\n\r\n /**\r\n * Save All Schedule changes\r\n * @param {array} objList \r\n */\r\n function setAllScheduleChangesToStorage(objList) {\r\n if (objList == null || !objList.length > 0) {\r\n GenericService.removeAll(objType);\r\n }\r\n else {\r\n var scheduleChanges = { dates: objList, showScheduleChangesModal: true }\r\n GenericService.saveOne(scheduleChanges, objType, objCallback);\r\n }\r\n }\r\n\r\n /**\r\n * Get all Schedule changes\r\n */\r\n function getScheduleChangesFromStorage() {\r\n var dateList = [];\r\n var scheduleChanges = GenericService.getOne(objType, objCallback);\r\n\r\n if (scheduleChanges != null && scheduleChanges.dates != null) {\r\n scheduleChanges.dates.forEach(function (dateS) {\r\n var stringToDate = moment.utc(dateS);\r\n dateList.push(stringToDate);\r\n });\r\n }\r\n\r\n return dateList;\r\n }\r\n\r\n /* Update scheduleChanges object to storage\r\n * @memberof ScheduleAcknowledgeFactory\r\n * @param {bool} canShowModal whether the modal can be display\r\n */\r\n function updateShowScheduleChangesModal(canShowModal) {\r\n var scheduleChanges = GenericService.getOne(objType, objCallback);\r\n scheduleChanges.showScheduleChangesModal = canShowModal;\r\n GenericService.saveOne(scheduleChanges, objType, objCallback);\r\n }\r\n\r\n /**\r\n * ShowScheduleChangesModal check\r\n * @memberof ScheduleAcknowledgeFactory\r\n * @returns {bool} returns the value of showScheduleChangesModal property\r\n */\r\n function showScheduleChangesModal() {\r\n var scheduleChanges = GenericService.getOne(objType, objCallback);\r\n\r\n if (scheduleChanges && scheduleChanges.dates != null && scheduleChanges.dates.length > 0) {\r\n var fistChange = moment.utc(scheduleChanges.dates[0]);\r\n var today = moment.utc();\r\n if (defaultCalendarDate) {\r\n today = moment.utc(defaultCalendarDate);\r\n }\r\n var datediff = fistChange.diff(today, 'days');\r\n\r\n return datediff <= 1 && scheduleChanges.showScheduleChangesModal;\r\n\r\n } else {\r\n return false;\r\n }\r\n }\r\n\r\n function hasScheduleChanges() {\r\n var dates = getScheduleChangesFromStorage();\r\n return dates != null && dates.length > 0;\r\n }\r\n\r\n /**\r\n * Acknowledge Changes \r\n * @param {date} dateFrom The first schedule change date\r\n * @param {date} dateTo The last schedule change date\r\n * @returns {promise} response\r\n */\r\n function acknowledgeChanges() {\r\n //get dates from local storage\r\n var datesToAcknowledge = getScheduleChangesFromStorage();\r\n\r\n return $http.post(apiUrl + '/ScheduleAcknowledge/AcknowledgeScheduleChanges', datesToAcknowledge, { 'Content-Type': 'application/json' })\r\n .then(res => updateScheduleChangesCallBack(res))\r\n .catch(res => acknowledgeFailedCallBack(res));\r\n }\r\n\r\n /**\r\n * Update Schedule changes dates\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} response\r\n */\r\n function updateScheduleChangesCallBack(res) {\r\n response.success = res.data.success;\r\n if (res.data.success) {\r\n //update local storage\r\n setAllScheduleChangesToStorage(res.data.data.DatesWithChanges);\r\n response.message = \"Success! Your Acknowledge has been sent\";\r\n response.Results = res.data.data.Results;\r\n }\r\n else {\r\n response.message = res.data.errorMessage\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * The callback function upon failure on submit\r\n * @returns {object} response\r\n */\r\n function acknowledgeFailedCallBack(res) {\r\n response.success = false;\r\n response.message = \"Oops! Something went wrong\"\r\n if (res.data.data && res.data.data.Results) {\r\n response.Results = res.data.data.Results;\r\n }\r\n return response;\r\n }\r\n\r\n\r\n\r\n return service;\r\n }\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('SearchFlightsCtrl', SearchFlightsCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SearchFlightsCtrl\r\n * @description \r\n * Search Flight info modal\r\n * @ngInject\r\n */ \r\nfunction SearchFlightsCtrl($scope, $uibModalInstance, $route, $location, defaultCalendarDate, SearchFlightsFactory, GroundDutyFactory, FlightFactory) {\t\t\t\r\n\t\t\r\n $scope.showContent = 'search';\r\n $scope.hasError = false;\r\n $scope.flightFound = null;\r\n\r\n $scope.searchFlights = searchFlights;\r\n $scope.searchCriteriaContent = searchCriteriaContent;\r\n $scope.closeModal = closeModal;\r\n $scope.gotoSelectedFlightInfo = gotoSelectedFlightInfo;\r\n $scope.validationFormError = '';\r\n $scope.hasPublishedRoster = true;\r\n\r\n //Date picker:\r\n $scope.openDatepicker = openDatepicker;\r\n var today = new Date().toUTC();\r\n if (defaultCalendarDate) {\r\n today = new Date(defaultCalendarDate).toUTC();\r\n }\r\n function openDatepicker() {\r\n $scope.searchCriteria.flightDatePicker.opened = true;\r\n }\r\n updateSearchCriteriaScope();\r\n \r\n function updateSearchCriteriaScope(){\r\n var fromDate = null;\r\n var toDate = null; \r\n \r\n var groundDutyDates = GroundDutyFactory.getFirstAndLastDateOfGroundDuties();\r\n var flightDates = FlightFactory.getTheFirstAndTheLastFlightDates();\r\n \r\n if (groundDutyDates && flightDates && groundDutyDates.firstDate && flightDates.firstDate) {\r\n fromDate = groundDutyDates.firstDate < flightDates.firstDate ? groundDutyDates.firstDate : flightDates.firstDate;\r\n toDate = groundDutyDates.lastDate > flightDates.lastDate ? groundDutyDates.lastDate : flightDates.lastDate;\r\n }\r\n else{\r\n $scope.hasPublishedRoster = false;\r\n $scope.showContent=\"results\"\r\n $scope.hasError = true;\r\n } \r\n \r\n $scope.searchCriteria = {\r\n flightDatePicker: {\r\n value: today,\r\n format: 'dd-MM-yyyy',\r\n opened: false,\r\n options: {\r\n minDate: fromDate,\r\n maxDate: toDate\r\n }\r\n },\r\n flightNo: \"\",\r\n departure: \"\",\r\n arrival:\"\"\r\n }\r\n }\r\n\r\n function searchFlights() {\r\n $scope.hasError = false;\r\n if($scope.searchCriteria.flightNo.length==0 &&\r\n $scope.searchCriteria.departure.length==0 &&\r\n $scope.searchCriteria.arrival.length==0 )\r\n {\r\n $scope.validationFormError = 'Ensure that at least one optional value is provided.'\r\n }\r\n else{\r\n $scope.showContent = 'loading';\r\n \r\n SearchFlightsFactory.getFlights($scope.searchCriteria) \r\n .then(res => handleResponse(res))\r\n .catch(res => handleFailedResponse(res));\r\n }\r\n }\r\n\r\n function handleResponse(res) {\r\n $scope.showContent = 'results';\r\n if (res.data && res.data.success && res.data.data) {\r\n $scope.flightsFound = res.data.data;\r\n\r\n //auto redirect when only one flight in results:\r\n // if($scope.flightsFound.lenght == 1){\r\n // gotoSelectedFlightInfo($scope.flightsFound[0].flightId, $scope.flightsFound[0].flightDate, $scope.flightsFound[0].flightNo, $scope.flightsFound[0].departure);\r\n // }\r\n } else {\r\n $scope.hasError = true;\r\n }\r\n\r\n }\r\n\r\n function handleFailedResponse(res) {\r\n $scope.showContent = 'results';\r\n $scope.hasError = true;\r\n }\t\r\n\r\n\r\n function searchCriteriaContent(){\r\n $scope.showContent = 'search';\r\n }\r\n\r\n /**\r\n * Redirect to selected flight info\r\n */\r\n function gotoSelectedFlightInfo(flightId, flightDate, flightNo, departure) {\r\n closeModal();\r\n $location.path('/selectedflightinfo/' + flightId + '/' + flightDate + '/' + flightNo+ '/' + departure);\r\n }\r\n\r\n /**\r\n * Close the modal\r\n * @memberof SearchPastGDCtrl\r\n */\r\n function closeModal() {\r\n $uibModalInstance.close('cancel');\r\n } \r\n\r\n}})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('SearchFlightsFactory', SearchFlightsFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SearchFlightsFactory\r\n * @description \r\n * Get selected flight info\r\n * @ngInject\r\n */ \r\nfunction SearchFlightsFactory($http, $q, apiUrl,$timeout) {\r\n\r\n var service = {\r\n getFlights: getFlights,\r\n getFlightInfo: getFlightInfo\r\n };\r\n\r\n function getFlights(criteria, callback) {\r\n //test UI:\r\n //return getFlightsDummy(criteria)\r\n\r\n var flightDate = criteria.flightDatePicker.value.toString('yyyy-MM-dd');\r\n var uri = encodeURI(apiUrl + '/SearchFlights/GetFlights?flightDate=' + flightDate + \r\n '&flightNo=' + criteria.flightNo + \r\n '&departure=' + criteria.departure +\r\n '&arrival=' + criteria.arrival);\r\n\r\n return $http.get(uri, { 'Content-Type': 'application/json' })\r\n .catch(callback); \r\n\r\n \r\n } \r\n\r\n function getFlightInfo(flightId, flightDate, flightNo, departure, callback){\r\n var flightDateStr = flightDate.toString('yyyy-MM-dd');\r\n\r\n // $http({\r\n // url: apiUrl + '/SearchFlights/GetFlightInfo', \r\n // method: \"GET\",\r\n // contentType: \"application/json\",\r\n // params: {flightId: flightId, flightDate: flightDateStr, flightNo: flightNo, departure: departure}\r\n // });\r\n\r\n var uri = encodeURI(apiUrl + '/SearchFlights/GetFlightInfo?flightId=' + flightId + \r\n '&flightDate=' + flightDateStr + \r\n '&flightNo=' + flightNo + \r\n '&departure=' + departure);\r\n\r\n return $http.get(uri, { 'Content-Type': 'application/json' })\r\n .catch(callback); \r\n\r\n }\r\n\r\n\r\n function getFlightsDummy(criteria) {\r\n // Create a deferred object to handle the promise\r\n var deferred = $q.defer();\r\n // Simulate an asynchronous operation (e.g., API call) with a delay\r\n $timeout(function(){\r\n var flightDate = criteria.flightDatePicker.value.toString('yyyy-MM-dd');\r\n\r\n // Simulate getting flight data asynchronously\r\n var testSuccessResults = {\r\n data: getDummyFlightResults(),\r\n success: true,\r\n errorMessage: \"\"\r\n };\r\n\r\n // Resolve the promise with the retrieved data\r\n deferred.resolve(testSuccessResults);\r\n },2000);\r\n\r\n \r\n\r\n // Return the promise\r\n return deferred.promise;\r\n }\r\n\r\n function getDummyFlightResults(){\r\n return {\r\n \"FlightsFound\": \r\n [{\r\n \"Id\": 1,\r\n \"FlightNo\": \"A3123\",\r\n \"FlightDate\": \"2023-10-20T00:00:00\",\r\n \"Registration\":\"AAA-OK1\",\r\n \"STD\": \"2023-10-20T08:00:00\",\r\n \"STA\": \"2023-10-20T12:00:00\",\r\n \"Departure\": \"ATH\",\r\n \"Arrival\": \"SKG\"\r\n },\r\n {\r\n \"Id\": 2,\r\n \"FlightNo\": \"A3789\",\r\n \"FlightDate\": \"2023-10-21T00:00:00\",\r\n \"Registration\":\"AAA-OK2\",\r\n \"STD\": \"2023-10-21T15:30:00\",\r\n \"STA\": \"2023-10-21T19:30:00\",\r\n \"Departure\": \"SKG\",\r\n \"Arrival\": \"ATH\"\r\n },\r\n {\r\n \"Id\": 3,\r\n \"FlightNo\": \"OA456\",\r\n \"FlightDate\": \"2023-10-22T00:00:00\",\r\n \"Registration\":\"CCC-OK3\",\r\n \"STD\": \"2023-10-22T10:15:00\",\r\n \"STA\": \"2023-10-22T14:15:00\",\r\n \"Departure\": \"ATH\",\r\n \"Arrival\": \"SKG\"\r\n }]\r\n };\r\n }\r\n\r\n\r\n return service;\r\n}\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('SelectedFlightCtrl', SelectedFlightCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SelectedFlightCtrl\r\n * @description \r\n * Show selected Flight info page\r\n * @ngInject\r\n */ \r\nfunction SelectedFlightCtrl($scope, $routeParams, defaultCalendarDate, SearchFlightsFactory, $timeout, waterUpliftSupportingAcTypes) {\t\t\t\r\n \r\n //get value from routeParams:\r\n var flightId = $routeParams.flightId;\r\n var flightDate = $routeParams.flightDate;\r\n var flightNo = $routeParams.flightNo;\r\n var departure = $routeParams.departure;\r\n\r\n window.addEventListener('online', function (e) { $timeout(checkConnectionStatus()); });\r\n $scope.init = checkConnectionStatus();\r\n $scope.contentToShow = \"loading\";\r\n $scope.flightInfo = null;\r\n $scope.hasFlightInfo = false;\r\n $scope.pilotCrewMembers = [];\r\n $scope.cabinCrewMembers = [];\r\n $scope.dhcCrewMembers = [];\r\n $scope.waterQuantity = null;\r\n $scope.supportsWaterUpliftAcType = false;\r\n $scope.crewRouteInfoPanel = {\r\n hasAircraftPositions: true,\r\n crewRouteDuties: []\r\n };\r\n\r\n /**\r\n * Checks if the client is online or offline \r\n * @memberof SelectedFlightCtrl \r\n */\r\n function checkConnectionStatus() {\r\n var isOnline = window.navigator.onLine;\r\n if (isOnline) {\r\n getFlightInfo();\r\n }\r\n else {\r\n showError(\"Please check your internet connection!\");\r\n }\r\n }\r\n\r\n function getFlightInfo(){\r\n SearchFlightsFactory.getFlightInfo(flightId, flightDate, flightNo, departure) \r\n .then(res => handleResponse(res))\r\n .catch(res => handleFailedResponse(res));\r\n }\r\n\r\n function handleResponse(res) {\r\n if(res.data.success){\r\n if ( res.data.data && res.data.data.Flight) {\r\n $scope.flightInfo = res.data.data;\r\n\r\n updateFlightInfoScopes(res.data.data);\r\n updateCrewMembersScopes();\r\n updatePaxPanelScopes();\r\n\r\n $scope.contentToShow = 'results';\r\n $scope.hasFlightInfo = true;\r\n }\r\n else {\r\n showError(\"Flight Info not found.\");\r\n }\r\n }else{\r\n showError(res.data.errorMessage);\r\n }\r\n }\r\n\r\n function handleFailedResponse(res) {\r\n $scope.contentToShow = 'results';\r\n $scope.hasError = true;\r\n showError(res.errorMessage);\r\n }\t\r\n\r\n /**\r\n * Displays the error message\r\n * @memberof SelectedFlightCtrl \r\n * @param {string} message message to display\r\n */\r\n function showError(message) {\r\n $scope.contentToShow = \"error\";\r\n $scope.errorMessage = message;\r\n }\r\n\r\n function updateCrewMembersScopes(){\r\n $scope.pilotCrewMembers = $scope.flightInfo.CrewInfo.filter(x => (x.PositionCode == 'CP' || x.PositionCode == \"FO\") && !x.DHC);\r\n $scope.cabinCrewMembers = $scope.flightInfo.CrewInfo.filter(x => (x.PositionCode == 'SA' || x.PositionCode == \"FA\") && !x.DHC);\r\n $scope.dhcCrewMembers = $scope.flightInfo.CrewInfo.filter(x => x.DHC);\r\n }\r\n\r\n function updatePaxPanelScopes(){\r\n $scope.supportsWaterUpliftAcType = waterUpliftSupportingAcTypes.includes($scope.flightInfo.AcType);\r\n getWaterQuantity();\r\n }\r\n \r\n function getWaterQuantity(){\r\n var totalPax = $scope.flightInfo.Flight.BOOKED_C + $scope.flightInfo.Flight.BOOKED_Y;\r\n var startDate = moment($scope.flightInfo.Flight.STD);\r\n var endDate = moment($scope.flightInfo.Flight.STA);\r\n var duration = moment.duration(endDate.diff(startDate)).asHours();\r\n var waterQuantity = (0,18 * totalPax * duration)/200;\r\n var formattedwaterQuantity = waterQuantity.toString().substring(0,4);\r\n $scope.waterQuantity = formattedwaterQuantity;\r\n if(waterQuantity){\r\n $scope.supportsWaterUpliftAcType = true;\r\n }\r\n }\r\n\r\n function updateFlightInfoScopes(flightInfoObj){\r\n var flight = {};\r\n flight.showPreviousAcPos = true;\r\n flight.showNextAcPos = true;\r\n flight.hasChangeAircraft = false;\r\n flight.DutyType = 'Flight';\r\n \r\n flight.FlightId = flightInfoObj.Flight.FlightId;\r\n flight.FlightNo = flightInfoObj.Flight.FlightNo;\r\n flight.Departure = flightInfoObj.Flight.DEP;\r\n flight.Arrival = flightInfoObj.Flight.ARR;\r\n flight.AcTailNo = flightInfoObj.Flight.Registration;\r\n flight.AcType = flightInfoObj.Flight.AcType;\r\n flight.DepartureStand = flightInfoObj.Flight.DEPSTAND;\r\n flight.ArrivalStand = flightInfoObj.Flight.ARRSTAND;\r\n flight.BookedC = flightInfoObj.Flight.BOOKED_C;\r\n flight.BookedY = flightInfoObj.Flight.BOOKED_Y;\r\n flight.ScheduledDeparture = flightInfoObj.Flight.STD;\r\n var STD = new Date(flight.ScheduledDeparture);\r\n flight.ScheduledDepartureDateUTC = STD.toString('yyyy-MM-dd');\r\n flight.ScheduledDepartureTimeUTC = STD.toString('HH:mm');\r\n flight.ScheduledArrival = flightInfoObj.Flight.STA;\r\n flight.CTOT = flightInfoObj.Flight.CTOT;\r\n flight.ETD = flightInfoObj.Flight.ETD;\r\n flight.ATD = flightInfoObj.Flight.ATD;\r\n flight.ETA = flightInfoObj.Flight.ETA;\r\n flight.ATA = flightInfoObj.Flight.ATA;\r\n flight.DepartureCountryISO = flightInfoObj.Flight.DepartureCountryISO;\r\n flight.ArrivalCountryISO = flightInfoObj.Flight.ArrivalCountryISO;\r\n flight.DepartureEU = flightInfoObj.Flight.DepartureEU;\r\n flight.ArrivalEU = flightInfoObj.Flight.ArrivalEU;\r\n flight.DepartureSchengen = flightInfoObj.Flight.DepartureSchengen;\r\n flight.ArrivalSchengen = flightInfoObj.Flight.ArrivalSchengen;\r\n \r\n var diffMin = Date.DifferenceInMinutes(flight.ScheduledDeparture, flight.ScheduledArrival);\r\n flight.BTime = Date.MinutesToStringSimple(diffMin);\r\n \tflight.Delay = moment(flight.ATD).diff(moment(flight.ScheduledDeparture), 'minutes') || \"\";\r\n\t flight.ArrDelay = moment(flight.ATA).diff(moment(flight.ScheduledArrival), 'minutes') || \"\";\r\n flight.flightDelays = {};\r\n flight.flightDelays.TotalDelay = flightInfoObj.FlightDelays.TotalDelay;\r\n flight.flightDelays.UnJustified = flightInfoObj.FlightDelays.UnJustified;\r\n flight.flightDelays.DC93 = flightInfoObj.FlightDelays.DC93;\r\n flight.flightDelays.DC9 = flightInfoObj.FlightDelays.DC9;\r\n //flight.crewMeals : no info\r\n \r\n flight.aircaftPositions = flightInfoObj.AircaftPositions;\r\n\r\n $scope.crewRouteInfoPanel.crewRouteDuties.push(flight);\r\n }\r\n\r\n}})();","(function () {\r\n\r\n a3_cabin_reports.directive('traineeSyllabus', traineeSyllabus);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name traineeSyllabus\r\n * @restrict E\r\n * @description\r\n * Initialize read only view of submitted syllabus\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n\r\n function traineeSyllabus() {\r\n function link(scope) { \r\n setSyllabus(scope.traineeSession);\r\n function setSyllabus(traineeSession) {\r\n var traineeSessionItems = [];\r\n scope.phase.Syllabus.ActiveVersion.SyllabusItems.forEach(function (item) {\r\n if(item.Active == true){\r\n var syllabusItem = JSON.parse(JSON.stringify(item));\r\n syllabusItem.Tries = [];\r\n syllabusItem.Selected = false;\r\n \r\n var relatedSessionItem = null;\r\n if(scope.type == \"signature\"){\r\n relatedSessionItem = traineeSession.Items.find(x => x.Id == syllabusItem.Id);\r\n }\r\n else{\r\n relatedSessionItem = traineeSession.Items.find(x => x.SyllabusItemId == syllabusItem.Id); \r\n }\r\n \r\n if(relatedSessionItem){\r\n syllabusItem.Selected = true;\r\n syllabusItem.Tries = relatedSessionItem.Tries;\r\n syllabusItem.hasRemarks = relatedSessionItem.Tries.some(x => x.Comments && x.Comments.length>0) ||\r\n relatedSessionItem.Tries.some(t=> t.TryGrading.Competences.some(x => x.Comments && x.Comments.length>0));\r\n syllabusItem.Tries.forEach(function(attempt){\r\n attempt.Selected = true;\r\n });\r\n }\r\n \r\n if(scope.type == \"signature\"){\r\n setPanelStyleByProgress(syllabusItem); \r\n }\r\n else{\r\n setPanelStyleBySelected(syllabusItem); \r\n } \r\n traineeSessionItems.push(syllabusItem);\r\n }\r\n \r\n });\r\n \r\n scope.traineeSession.ItemsGrouped = [];\r\n scope.traineeSession.ItemsGrouped = SyllabusGrouping(traineeSessionItems); \r\n }\r\n\r\n function setPanelStyleByProgress(item){\r\n var historyTriesCount = item.Tries.length;\r\n var newTriesCount = item.Tries.filter(x => !x.isReadOnly && x.Selected).length;\r\n item.TriesPerformedCount = historyTriesCount + newTriesCount;\r\n\r\n var completedItem = item.TriesPerformedCount >= item.MandatoryCount;\r\n\r\n if(item.MandatoryCount == 0){ //non-mandatory items are considered completed if performed at least once\r\n completedItem = item.TriesPerformedCount>=1;\r\n }\r\n\r\n if(completedItem){\r\n item.PanelClass = 'panel-green panel-border-left-green ';\r\n }\r\n else{\r\n item.PanelClass = 'panel-border-left-blue ';\r\n }\r\n }\r\n\r\n function setPanelStyleBySelected(item){\r\n var historyTriesCount = item.Tries.length;\r\n \r\n item.TriesPerformedCount = historyTriesCount;\r\n\r\n var completedItem = item.TriesPerformedCount >= item.Mandatory;\r\n\r\n if(completedItem){\r\n item.PanelClass = 'panel-green panel-border-left-green ';\r\n }\r\n else{\r\n item.PanelClass = 'panel-border-left-blue ';\r\n }\r\n }\r\n\r\n function SyllabusGrouping(items) {\r\n //Syllabus Items Group By 'GroupId'\r\n var syllabusGroups = [];\r\n items.forEach(function (item) {\r\n if (!syllabusGroups.some(x => x.Id == item.SelectedGroup.Id)) {\r\n if (!item.SelectedGroup) {\r\n item.SelectedGroup = {\r\n Id: 0,\r\n Title: 'General'\r\n };\r\n }\r\n\r\n var syllabusGroup = {\r\n Id: item.SelectedGroup.Id,\r\n Title: item.SelectedGroup.Title ? item.SelectedGroup.Title : 'General',\r\n Items: []\r\n };\r\n\r\n syllabusGroup.Items.push(item);\r\n syllabusGroups.push(syllabusGroup);\r\n }\r\n else {\r\n syllabusGroups.filter(x => x.Id == item.SelectedGroup.Id)[0].Items.push(item);\r\n }\r\n });\r\n\r\n return syllabusGroups;\r\n }\r\n\r\n }\r\n return {\r\n restrict: 'E',\r\n templateUrl: 'views/TraineeCourse/trainee-syllabus.tpl.html',\r\n scope : { phase:\"=\", traineeSession:\"=\", type:\"=\"},\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.controller('TraineeCourseCtrl', TraineeCourseCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name TraineeCourseCtrl\r\n * @description \r\n *\r\n * @ngInject\r\n */\r\nfunction TraineeCourseCtrl($scope, $routeParams, TraineeCoursesDetailsFactory, TrainingSessionFactory, $location){\r\n var traineeCourseId = Number($routeParams.traineeCourseId);\r\n $scope.hasError = false;\r\n $scope.isLoading = true;\r\n $scope.courseDate = $routeParams.date;\r\n $scope.isTraineeView = true;\r\n $scope.gotoCalendar = gotoCalendar;\r\n $scope.setSelectedPhase = setSelectedPhase;\r\n\r\n $scope.responseObj = { success: false, message: '', Results: [] };\r\n $scope.results = [];\r\n $scope.showWarning = false;\r\n\r\n TraineeCoursesDetailsFactory.getTraineeCourse(traineeCourseId).then(res => handleSubmitResponse(res))\r\n .catch(res => handleFailedResponse(res)); \r\n\r\n function handleSubmitResponse(res) {\r\n $scope.responseObj = res;\r\n if(res.success){\r\n $scope.traineeCourse = res.Results.data.traineeCourse;\r\n $scope.courseDetails = res.Results.data.courseDetails;\r\n\r\n $scope.traineeCourse.Phases.forEach(function(phase){\r\n phase.StatusClass = '';\r\n \r\n if(phase.PhaseStatus=='InProgress'){\r\n phase.StatusClass=\"border-left-blue\";\r\n phase.TextClass=\"text-blue\";\r\n phase.BtnClass=\"bg-blue text-white\";\r\n }\r\n else if(phase.PhaseStatus=='Pending'){\r\n phase.StatusClass=\"border-left-gray \";\r\n phase.TextClass=\"text-gray\";\r\n phase.BtnClass=\"bg-gray text-white\";\r\n }\r\n else if(phase.PhaseStatus=='Completed'){\r\n phase.StatusClass=\"border-left-green\";\r\n phase.TextClass=\"text-green\";\r\n phase.BtnClass=\"bg-green text-white\";\r\n }\r\n \r\n });\r\n \r\n $scope.traineeCourse.Phases.forEach(function (phase) {\r\n phase.Sessions.forEach(function (sessionTrainee) {\r\n if (sessionTrainee) {\r\n $scope.traineeSession = sessionTrainee;\r\n $scope.traineeSession.hasDayGrading = sessionTrainee.DayGrading.Comments || (sessionTrainee.DayGrading.GradeType != 'NotSet' && sessionTrainee.DayGrading.Grade) || sessionTrainee.DayGrading.Competences.length>0;\r\n $scope.traineeSession.hasReleaseGrading = sessionTrainee.ReleaseGrading.Comments || (sessionTrainee.ReleaseGrading.GradeType != 'NotSet' && sessionTrainee.ReleaseGrading.Grade) || sessionTrainee.ReleaseGrading.Competences.length>0;\r\n $scope.traineeSession.AcTypes = [];\r\n $scope.traineeSession.AcTypes = [...new Set($scope.traineeSession.Sectors.map(ses => ses.AcType))];\r\n //GroupBy AcType\r\n $scope.traineeSession.SectorsByAcType = [];\r\n $scope.traineeSession.AcTypes.forEach(function(acType){\r\n var group = {\r\n AcType: acType,\r\n Sectors: $scope.traineeSession.Sectors.filter(x => x.AcType == acType)\r\n };\r\n $scope.traineeSession.SectorsByAcType.push(group); \r\n });\r\n } else {\r\n trainee.Session = {\r\n Released: course.selectedPhase.ModuleType == \"Training\" ? false : true,\r\n CrewId: trainee.CrewId,\r\n Items: [],\r\n Absent: false,\r\n DayGrading: {\r\n Comments: null,\r\n Grade: null,\r\n Competences: []\r\n },\r\n ReleaseGrading: {\r\n Comments: null,\r\n Grade: null,\r\n Competences: []\r\n }, \r\n NeedsAdditionalTraining: false,\r\n AdditionalTrainingRemarks: null,\r\n CompleteAdditionalTraining: false\r\n }\r\n }\r\n });\r\n \r\n getSelectedPhase($scope.traineeCourse);\r\n\r\n var phaseId = $scope.traineeCourse.Phases[0].PhaseId;\r\n initPhaseDetails(phaseId);\r\n });\r\n } else {\r\n $scope.showWarning = true;\r\n $scope.responseObj;\r\n }\r\n } \r\n \r\n \r\n function initPhaseDetails(phaseId) {\r\n $scope.selectedPhase = $scope.courseDetails.CoursePhases.find(x => x.Id == phaseId);\r\n\r\n $scope.traineePhase = $scope.traineeCourse.Phases.find(x => x.PhaseId == phaseId);\r\n $scope.selectedTraineePhase = $scope.courseDetails.CoursePhases.find(x => x.Id == phaseId);\r\n $scope.traineeInstructions = $scope.selectedPhase.TraineeInstructions;\r\n $scope.examinerInstructions = $scope.selectedPhase.ExaminerInstructions;\r\n\r\n $scope.flatSullabusItems = [];\r\n $scope.traineeCourse.Phases.forEach(function (phase) {\r\n phase.Sessions.forEach(function (session) {\r\n session.Items.forEach(function (item) {\r\n var flatItem = TrainingSessionFactory.createFlatHistorySullabusItem($scope.traineeCourse, phase, session, item);\r\n $scope.flatSullabusItems.push(flatItem);\r\n });\r\n });\r\n });\r\n\r\n $scope.flatCourseSullabusItems = [];\r\n $scope.courseDetails.CoursePhases.filter(x => x.Syllabus).forEach(function (phase, index, array) {\r\n phase.Syllabus.ActiveVersion.SyllabusItems.forEach(function (syllabusItem) {\r\n var syllabusItemHistory = $scope.flatSullabusItems.filter(item => item.ItemId == syllabusItem.Id);\r\n $scope.flatCourseSullabusItems.push(syllabusItemHistory);\r\n });\r\n\r\n });\r\n $scope.isLoading = false;\r\n }\r\n\r\n function handleFailedResponse(res) {\r\n $scope.hasError = true;\r\n }\t\t\r\n\r\n function getSelectedPhase(course) {\r\n var hasSelectedPhase = false;\r\n var phases = course.Phases;\r\n\r\n phases.forEach(function (phase, index, array) {\r\n phase.isFirst = index == 0;\r\n phase.isLast = (index + 1 == array.length);\r\n // Select the first InProgress & selected phase\r\n if (!hasSelectedPhase && phase.Status == \"InProgress\" && phase.isSelected) {\r\n phase.Selected = true;\r\n hasSelectedPhase = true;\r\n }\r\n });\r\n \r\n // Select the first InProgress phase\r\n if (!hasSelectedPhase && phases.some(x => x.Status == \"InProgress\")) {\r\n phases.find(x => x.Status == \"InProgress\").Selected = true;\r\n hasSelectedPhase = true;\r\n }\r\n\r\n if (!hasSelectedPhase) {\r\n phases.find(x => x.isFirst).Selected = true;\r\n }\r\n\r\n $scope.selectedPhase = phases.find(x => x.Selected);\r\n return $scope.selectedPhase;\r\n }\r\n\r\n function setSelectedPhase(phaseId){\r\n\r\n $scope.selectedPhase = $scope.courseDetails.CoursePhases.find(x => x.Id == phaseId);\r\n $scope.courseDetails.CoursePhases.find(x => x.Id == phaseId).Selected = true;\r\n initPhaseDetails(phaseId);\r\n return $scope.selectedPhase;\r\n }\r\n\r\n function gotoCalendar() {\r\n $location.path(\"/\");\r\n }\r\n\r\n}\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('traineeCoursesDetails', traineeCoursesDetails);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name traineeCoursesDetails\r\n * @restrict E\r\n * @description\r\n * Implementation of trainee Courses Details\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function traineeCoursesDetails(TraineeCoursesDetailsFactory, $location, $uibModal, $routeParams) {\r\n function link(scope, attrs) {\r\n // scope.getTraineeCourse = getTraineeCourse;\r\n scope.goToTraineeCourse = goToTraineeCourse;\r\n scope.goToTraineeFlightCourse = goToTraineeFlightCourse;\r\n scope.HasTraineeView = true;\r\n scope.isLoading = false;\r\n scope.traineeCourses = [];\r\n scope.traineeFlightCourses = [];\r\n\r\n var dutyId = scope.groundDutyId;\r\n if(dutyId != null){\r\n scope.traineeCourses = TraineeCoursesDetailsFactory.getTraineeGroundCourses(dutyId); \r\n }\r\n\r\n if(scope.flightId != null || scope.Flight != null){\r\n var flightId = scope.flightId != null ? scope.flightId : scope.Flight.FlightId;\r\n }\t\r\n if(flightId != null){\r\n scope.traineeFlightCourses = TraineeCoursesDetailsFactory.getTraineeFlightCourses(flightId); \t\r\n } \t\t\r\n \r\n if(scope.traineeCourses.length > 0){\r\n var date = scope.groundDuty.DutyDateS;\r\n }\r\n \r\n if(scope.traineeFlightCourses.length > 0){\r\n var flightDate = new moment(scope.flight.FlightDate).format(\"DD-MM-YYYY\");\r\n }\r\n manageCourseStatus(scope.traineeCourses, scope.traineeFlightCourses);\r\n\r\n function manageCourseStatus(traineeCourses, traineeFlightCourses){ \r\n traineeCourses.forEach(course => {\r\n //Pending\r\n if(course.Status == \"1\"){\r\n course.StatusClass = \"text-blue\";\r\n }\r\n //Completed\r\n else if(course.Status == \"2\"){\r\n course.StatusClass = \"text-green\";\r\n\r\n }\r\n //NotCompleted - stopped\r\n else if(course.Status == \"5\"){\r\n course.StatusClass = \"text-orange\";\r\n\r\n }\r\n }); \r\n traineeFlightCourses.forEach(course => {\r\n //Pending\r\n if(course.Status == \"1\"){\r\n course.StatusClass = \"text-blue\";\r\n }\r\n //Completed\r\n else if(course.Status == \"2\"){\r\n course.StatusClass = \"text-green\";\r\n \r\n }\r\n //NotCompleted - stopped\r\n else if(course.Status == \"5\"){\r\n course.StatusClass = \"text-orange\";\r\n \r\n }\r\n \r\n }); \r\n\r\n }\r\n\r\n /**\r\n * Redirect to Course Session\r\n */\r\n function goToTraineeCourse(traineeCourseId) {\r\n $location.path('/traineecourse/' + traineeCourseId + '/' + dutyId + '/' + date);\r\n }\r\n\r\n function goToTraineeFlightCourse(traineeCourseId){\r\n $location.path('/traineecourse/' + traineeCourseId + '/' + flightId + '/' + flightDate);\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: true,\r\n templateUrl: 'views/TraineeCourse/trainee-courses-details.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('TraineeCoursesDetailsFactory', TraineeCoursesDetailsFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name TraineeCoursesDetailsFactory\r\n * @description \r\n * Get, Set and Submit Trainee Courses Details.\r\n * @ngInject\r\n */\r\n function TraineeCoursesDetailsFactory(localStorageMD5Service, $http, apiUrl, GenericService, $timeout) {\r\n\r\n var objTypeGround ='traineeCourses';\r\n var objTypeFlight ='traineeFlightCourses';\r\n\t\tvar objCallbackGround = TraineeCourses;\r\n var objCallbackFlights = TraineeFlightCourses;\r\n\r\n window.addEventListener('online', function (e) { $timeout(checkConnectionStatus()); });\r\n\r\n var response = { success: false, \r\n message: '', \r\n Results: []\r\n };\r\n\r\n var service = {\r\n setTraineeCoursesToStorage: setTraineeCoursesToStorage,\r\n getTraineeGroundCourses: getTraineeGroundCourses,\r\n getTraineeCourses: getTraineeCourses,\r\n getTraineeCourse: getTraineeCourse,\r\n setTraineeFlightCoursesToStorage: setTraineeFlightCoursesToStorage,\r\n getTraineeFlightCourses: getTraineeFlightCourses,\r\n getFlightCourses: getFlightCourses\r\n };\r\n\r\n function TraineeCourses() {\r\n this.DutyDate = null; \r\n this.Status = null; \r\n this.GroundDutyId = null;\r\n }\r\n\r\n function checkConnectionStatus() {\r\n response.success = false;\r\n response.message = \"Please check the internet connection!\";\r\n\r\n }\r\n\r\n /**\r\n * Set all the trainee courses\r\n * @memberof TraineeCoursesDetailsFactory\r\n * @param {array} objects A list of trainee courses.\r\n */\r\n\t\tfunction setTraineeCoursesToStorage(data) {\r\n GenericService.saveAll(data, objTypeGround, objCallbackGround);\t\r\n\t\t}\r\n\r\n function getTraineeGroundCourses(dutyId) {\r\n var results = [];\r\n var listOfValues = localStorageMD5Service.get(objTypeGround);\r\n if(listOfValues){\r\n var traineeCoursesPerDuty = listOfValues.filter(function (item) {\r\n return item.GroundDutyId == dutyId;\r\n });\r\n results = traineeCoursesPerDuty.map(function (item) {\r\n return item;\r\n });\r\n }\r\n\t\t\treturn (results);\r\n }\r\n\r\n function getTraineeCourses() {\r\n\t\t\treturn GenericService.list(objTypeGround,objCallbackGround);\r\n\t\t}\r\n\r\n function getFlightCourses() {\r\n return GenericService.list(objTypeFlight,objCallbackFlights);\r\n }\r\n\r\n function TraineeFlightCourses(){}\r\n\r\n function getTraineeCourse(traineeCourseId, callback) {\r\n return $http.get(apiUrl + '/Training/GetTraineeCourse?traineeCourseId=' + traineeCourseId, { 'Content-Type': 'application/json' })\r\n .then(res => updateTraineeCourseCallBack(res))\r\n .catch(res => traineeCourseFailedCallBack(res)); \r\n } \r\n\r\n function updateTraineeCourseCallBack(res) {\r\n response.success = res.data.success;\r\n if (res.data.success) { \r\n response.Results = res.data;\r\n }\r\n else {\r\n response.message = res.data.errorMessage\r\n }\r\n\r\n return response;\r\n }\r\n\r\n /**\r\n * The callback function upon failure on submit\r\n * @returns {object} response\r\n */\r\n function traineeCourseFailedCallBack(res) {\r\n if(!window.navigator.onLine){\r\n checkConnectionStatus();\r\n }\r\n else{\r\n response.success = false;\r\n response.message = \"Oops! Something went wrong\"\r\n \r\n //TODO::Check status=500 error: returns res = {data: {…}, status: 500, config: {…}, statusText: \"Internal Server Error\", headers: ƒ}\r\n // res.data.data is null\r\n if(res.data.data && res.data.data.Results){\r\n response.Results = res.data.data.Results;\r\n }else{\r\n //log results\r\n console.log(res);\r\n }\r\n }\r\n \r\n return response;\r\n }\r\n \r\n function setTraineeFlightCoursesToStorage(data) {\r\n GenericService.saveAll(data, objTypeFlight, objCallbackFlights);\r\n\t\t}\r\n \r\n function getTraineeFlightCourses(flightId) {\r\n var results = [];\r\n var listOfValues = localStorageMD5Service.get(objTypeFlight);\r\n if(listOfValues){\r\n var traineeCoursesPerDuty = listOfValues.filter(function (item) {\r\n return item.FlightId == flightId;\r\n });\r\n results = traineeCoursesPerDuty.map(function (item) {\r\n return item;\r\n });\r\n }\r\n\t\t\treturn (results);\r\n }\r\n return service;\r\n }\r\n\r\n})();\r\n","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.service(\"InfoAPIService\", InfoAPIService);\r\n\r\n\t/**\r\n\t* @memberof CabinReports\r\n\t* @ngdoc service\r\n\t* @name InfoAPIService\r\n\t* @description \r\n\t* Information service which gets latest pax and gate data\r\n\t* @ngInject\r\n\t*/\r\n\tfunction InfoAPIService($http, $q, apiUrl, LogService, UserFactory, SyncAPIService,\r\n\t\t\t\tFlightFactory, PaxInfoFactory, AircaftPositionsFactory, GroundDutyFactory, \r\n\t\t\t\tCampaignFactory, LuggageComplianceFactory, FlightCheckInsFactory, \r\n\t\t\t\tPhiloxeniaQuestionsFactory, FlightDelaysFactory, CustomerEventHistoryFactory) {\r\n\r\n\t\treturn {\r\n\t\t\tgetPax: getPax,\r\n\t\t\tsendCustomerIncident: sendCustomerIncident,\r\n\t\t\trefreshCrewRoute: refreshCrewRoute,\r\n\t\t\tupdateCrewRouteStatusSetter: updateCrewRouteStatusSetter,\r\n\t\t\tupdateFlightStatusSetter: updateFlightStatusSetter,\r\n\t\t\tupdateGroundStatusSetter: updateGroundStatusSetter,\r\n\t\t\tupdateStatusSetter: updateStatusSetter,\r\n\t\t\tupdateFlightLocalStorage: updateFlightLocalStorage,\r\n\t\t\tupdateGroundDutyLocalStorage: updateGroundDutyLocalStorage,\r\n\t\t\tupdateCrewCheckIn: updateCrewCheckIn,\r\n\t\t\tupdatePhiloxeniaQuestions: updatePhiloxeniaQuestions\r\n\t\t};\r\n\r\n\t\t/**\r\n\t\t * get latest Passenger information\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @return {object} promise\r\n\t\t */\r\n\t\tfunction getPax(flightId) {\r\n\r\n\t\t\t//Prepare to request training courses fetch\r\n\t\t\tvar flight = FlightFactory.getFlightFromTotalFlights(flightId);\r\n\r\n\t\t\tvar flightInfo = {\r\n\t\t\t\tFlightId: flightId,\r\n\t\t\t\tFlightCourses: flight ? flight.Courses : []\r\n\t\t\t};\r\n\r\n\t\t\tvar user = UserFactory.getUser();\r\n\t\t\tvar call = $q.defer();\r\n\r\n\t\t\t$http.post(apiUrl + '/info/Pax', flightInfo, { 'Content-Type': 'application/json' })\r\n\t\t\t\t.then(\r\n\t\t\t\t\tfunction (responseData) {\r\n\t\t\t\t\t\tif (responseData == undefined || responseData.data == undefined || responseData.data.data == undefined) {\r\n\t\t\t\t\t\t\tvar err = new Error();\r\n\t\t\t\t\t\t\terr.status = -1;\r\n\t\t\t\t\t\t\tvar msg = \"ResponseData error in info/gates :\" + JSON.stringify(responseData);\r\n\t\t\t\t\t\t\tLogService.debug(msg, err)\r\n\t\t\t\t\t\t\tcall.reject(err);\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\tvar newDutyInfo = responseData.data.data;\r\n\t\t\t\t\t\tnewDutyInfo.FlightId = flightId;\r\n\t\t\t\t\t\tupdateFlightLocalStorage(newDutyInfo);\r\n\t\t\t\t\t\tLuggageComplianceFactory.updateLuggageComplianceStorage(newDutyInfo.LuggageCompliance, flightId);\r\n\t\t\t\t\t\tupdateCrewCheckIn(newDutyInfo);\r\n\t\t\t\t\t\tupdatePhiloxeniaQuestions(newDutyInfo);\r\n\t\t\t\t\t\tFlightDelaysFactory.upsertFlightDelays(newDutyInfo.FlightDelays);\r\n\r\n\t\t\t\t\t\tcall.resolve(responseData);\r\n\t\t\t\t\t},\r\n\t\t\t\t\tfunction (err) {\r\n\t\t\t\t\t\tcall.reject(err);\r\n\t\t\t\t\t}\r\n\t\t\t\t);\r\n\t\t\treturn call.promise;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Send Customer Incident\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @return {object} promise\r\n\t\t */\r\n\t\tfunction sendCustomerIncident(flightDescription, question, description, imageStr) {\r\n\r\n\t\t\tvar user = UserFactory.getUser();\r\n\t\t\tvar call = $q.defer();\r\n\t\t\tvar customerIncident = { flightDescription: flightDescription, question: question, description: description, image: imageStr }\r\n\t\t\t$http.post(apiUrl + '/customer/Incident', customerIncident, { 'Content-Type': 'application/json' })\r\n\t\t\t\t.then(\r\n\t\t\t\t\tfunction (responseData) {\r\n\t\t\t\t\t\tif (responseData == undefined || responseData.data == undefined || responseData.data.data == undefined) {\r\n\t\t\t\t\t\t\tvar err = new Error();\r\n\t\t\t\t\t\t\terr.status = -1;\r\n\t\t\t\t\t\t\tvar msg = \"ResponseData error in customer/Incident :\" + JSON.stringify(responseData);\r\n\t\t\t\t\t\t\tLogService.debug(msg, err)\r\n\t\t\t\t\t\t\tcall.reject(err);\r\n\t\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tcall.resolve(responseData);\r\n\t\t\t\t\t},\r\n\t\t\t\t\tfunction (err) {\r\n\t\t\t\t\t\tcall.reject(err);\r\n\t\t\t\t\t}\r\n\t\t\t\t);\r\n\t\t\treturn call.promise;\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Gets latest info for each duty in a crew route\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @param {object} crewRouteDuty \r\n\t\t * @param {function} callback \r\n\t\t */\r\n\t\tfunction refreshCrewRoute(crewRouteDuty, callback) {\r\n\t\t\tvar crewRouteInfo = {\r\n\t\t\t\tDutyNo: crewRouteDuty.DutyNo,\r\n\t\t\t\tDutyDay: crewRouteDuty.DutyDay,\r\n\t\t\t\tRoute: crewRouteDuty.Route,\r\n\t\t\t\tFrom: crewRouteDuty.DutyBegin,\r\n\t\t\t\tTo: crewRouteDuty.DutyEnd,\r\n\t\t\t\tFlightCourses: crewRouteDuty.Courses,\r\n\t\t\t\tCurrentDutyDate: crewRouteDuty.CurrentDutyDate\r\n\t\t\t};\r\n\r\n\t\t\t//refresh route for the current day (Flight page)\r\n\t\t\tif (crewRouteDuty.CurrentDutyDate) {\r\n\t\t\t\treturn $http.post(apiUrl + '/info/RefreshFlight', crewRouteInfo, { 'Content-Type': 'application/json' })\r\n\t\t\t\t\t.then(callback);\r\n\t\t\t}\r\n\t\t\t//Refresh whole Crew Route (Crew Route oage)\r\n\t\t\telse {\r\n\t\t\t\treturn $http.post(apiUrl + '/info/RefreshCrewRoute', crewRouteInfo, { 'Content-Type': 'application/json' })\r\n\t\t\t\t\t.then(callback);\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Updates Route's Data Status depending on Refresh respond\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @param {object} newDuty - Refresh respond\r\n\t\t * @param {array} dataStatus \r\n\t\t */\r\n\t\tfunction updateCrewRouteStatusSetter(dataStatus, crewRouteStatuses) {\r\n\t\t\tif (crewRouteStatuses.meals) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Meals\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Meals\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (crewRouteStatuses.airportContacts) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Airport Contacts\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Airport Contacts\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (crewRouteStatuses.groundServices) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Ground Services\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Ground Services\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (crewRouteStatuses.aircraftDifferences) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Aircraft Differences\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Aircraft Differences\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (crewRouteStatuses.campaigns) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Campaigns\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Campaigns\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (crewRouteStatuses.airportHotels) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Hotels\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Hotels\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (crewRouteStatuses.crewAimsMemos) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Aims Memos\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Aims Memos\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tif (crewRouteStatuses.flightServiceEvents) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Flight Service Events\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Flight Service Events\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\t\t}\r\n\t\t/**\r\n\t\t * Updates Flight's Data Status depending on Refresh respond\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @param {object} newDuty - Refresh respond\r\n\t\t * @param {array} dataStatus \r\n\t\t */\r\n\t\tfunction updateFlightStatusSetter(newDuty, dataStatus) {\r\n\r\n\t\t\tif (newDuty.FlightInfo) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Flight Status\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t} else {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Flight Status\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (newDuty.AircraftPositions && newDuty.AircraftPositions.length > 0) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Aircraft Movement\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t} else {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Aircraft Movement\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (newDuty.FlightInfo && newDuty.FlightInfo.crew && newDuty.FlightInfo.crew.length > 0) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Crew Info\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t} else {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Crew Info\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (newDuty.FlightInfo && newDuty.FlightInfo.crew && newDuty.FlightInfo.crew.length > 0 && newDuty.FlightInfo.crew.filter(x => x.PhoneNumber != null).length > 0) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Crew Contacts\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t} else {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Crew Contacts\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (newDuty.CabinServiceManagementLists && newDuty.CabinServiceManagementLists.length > 0 && newDuty.CabinServiceManagementLists[0].ConnectingFlights && newDuty.CabinServiceManagementLists[0].ConnectingFlights.length > 0) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Connections\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t} else {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Connections\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (newDuty.CabinServiceManagementLists && newDuty.CabinServiceManagementLists.length > 0 && newDuty.CabinServiceManagementLists[0].ConnectingFlights && newDuty.CabinServiceManagementLists.length > 0) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Pax Info\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t} else {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Pax Info\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (newDuty.LuggageCompliance && newDuty.LuggageCompliance.length > 0) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Luggage Info\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t} else {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Luggage Info\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (newDuty.TrainingCourses && newDuty.TrainingCourses.length > 0) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Training Info\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t} else {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Training Info\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Updates Ground Duty's Data Status depending on Refresh respond\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @param {array} newDuty - Refresh respond\r\n\t\t * @param {array} dataStatus \r\n\t\t */\r\n\t\tfunction updateGroundStatusSetter(newDuty, dataStatus) {\r\n\t\t\tif (newDuty) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Duty Info\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t} else {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Duty\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\r\n\t\t\tif (newDuty && newDuty.RelatedGroundDuties && newDuty.RelatedGroundDuties.length > 1) {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Instructors\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Trainees\"], \"SUCCESS\", \"Successfully updated\");\r\n\t\t\t} else {\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Instructors\"], \"N/A\", \"No available data\");\r\n\t\t\t\tupdateStatusSetter(dataStatus, [\"Trainees\"], \"N/A\", \"No available data\");\r\n\t\t\t}\r\n\t\t}\r\n\r\n\r\n\t\t/**\r\n\t\t * Changes the state of Data Status\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @param {array} dataStatus \r\n\t\t * @param {array} array - Datatype to change\r\n\t\t * @param {string} status - New status\r\n\t\t * @param {string} text - New text\r\n\t\t */\r\n\t\tfunction updateStatusSetter(dataStatus, array, status, text) {\r\n\r\n\t\t\tvar objsTochange = dataStatus.filter(function (x) {\r\n\t\t\t\tvar res = array.filter(function (s) { return s == x.datatype });\r\n\t\t\t\treturn res.length > 0 ? true : false;\r\n\t\t\t});\r\n\r\n\t\t\tobjsTochange.forEach(function (x) {\r\n\t\t\t\tx.status = status;\r\n\t\t\t\tx.text = text;\r\n\r\n\t\t\t\tvar index = dataStatus.map(function (x) { return x.datatype }).indexOf(x.datatype);\r\n\t\t\t\tdataStatus[index] = x;\r\n\t\t\t});\r\n\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Update Flight Info in Local Storage\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @param {object} duty \r\n\t\t */\r\n\t\tfunction updateFlightLocalStorage(duty) {\r\n\t\t\t// save flight gates to local storage\r\n\t\t\t//var flightGates = duty.FlightGates;\r\n\t\t\t//FlightGateFactory.processUpdatedData(flightGates);\r\n\r\n\t\t\t//Update Aircraft positions\r\n\t\t\tif (duty.AircraftPositions != null && duty.AircraftPositions.length > 0) {\r\n\t\t\t\tAircaftPositionsFactory.updateAircraftPositionsToStorage(duty.AircraftPositions[0], duty.FlightInfo.FlightId);\r\n\t\t\t}\r\n\t\t\t// update flight to local storage\r\n\t\t\tFlightFactory.mergeFlightInfo(duty.FlightInfo, duty.ShowPaxNames);\r\n\t\t\t//Enrich flight info after sync\r\n\t\t\tSyncAPIService.updateCabinReportLocalEditFromSynch();\r\n\t\t\t// update paxinfo to local storage\r\n\r\n\t\t\tif (duty.CabinServiceManagementLists && duty.CabinServiceManagementLists.length > 0) {\r\n\t\t\t\tPaxInfoFactory.updatePaxInfo(duty.CabinServiceManagementLists[0]);\r\n\t\t\t}\r\n\r\n\r\n\t\t\tif (duty.Campaigns && duty.Campaigns.FlightsCampaigns.length > 0) {\r\n\t\t\t\tif (duty.CabinServiceManagementLists) {\r\n\t\t\t\t\tCampaignFactory.updateSeatNoPaxAssignments(duty.Campaigns.FlightsCampaigns, duty.CabinServiceManagementLists);\r\n\t\t\t\t}\r\n\t\t\t\tCampaignFactory.mergeCampaigns(duty.Campaigns);\r\n\t\t\t}\r\n\r\n\t\t\tif (duty.CustomerEventHistory && duty.CustomerEventHistory.length) {\r\n\t\t\t\tCustomerEventHistoryFactory.refreshPassengerHistory(duty.CustomerEventHistory);\r\n\t\t\t}\r\n\t\t\t// update messages to local storage\r\n\t\t\t// MessageFactory.markReadAsSynched(duty.Messages);\r\n\t\t\t// MessageFactory.storeMessagesFromServer(duty.Messages);\r\n\r\n\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Update Ground Duty Info in Local Storage\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @param {object} duty \r\n\t\t */\r\n\t\tfunction updateGroundDutyLocalStorage(duty) {\r\n\t\t\tGroundDutyFactory.mergeGroundDutyInfo(duty);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Update Flight crew check-in Info in Local Storage\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @param {object} duty \r\n\t\t */\r\n\t\tfunction updateCrewCheckIn(duty) {\r\n\t\t\tif (duty.FlightInfo) {\r\n\t\t\t\tFlightCheckInsFactory.updateFlightCrewCheckInToStorage(duty);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Update Philoxenia Questions for the current flight in Local Storage\r\n\t\t * @memberof InfoAPIService\r\n\t\t * @param {object} duty \r\n\t\t */\r\n\t\tfunction updatePhiloxeniaQuestions(duty) {\r\n\t\t\tif (duty.PhiloxeniaQuestions) {\r\n\t\t\t\tPhiloxeniaQuestionsFactory.updatePhiloxeniaQuestionsToStorage(duty.PhiloxeniaQuestions);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.service(\"SyncAPIService\", SyncAPIService);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc service\r\n * @name SyncAPIService\r\n * @description \r\n * Generic Sync service which sends all your reports and gets all the latest data\r\n * @ngInject\r\n */\r\n\r\n\r\n function SyncAPIService($http, $q, apiUrl, FlightFactory, ReportGuidFactory, CabinReportTemplateItemFactory, SyncLogFactory,\r\n CabinReportLocalEditFactory, CrewRouteFactory, CrewMealFactory, CabinReportSendToServerFactory, CabinReportSyncResultFactory, AircraftTypeFactory,\r\n DataCleanerFactory, WaterUpliftActionFactory, ACSupplyFactory, SpecialMealSourceFactory, SpecialMealTypeFactory, CCMSFactory, TravelValueIncompleteReasonFactory,\r\n CCMSCrewPositionFactory, MessageFactory, LogService, CrewAssessmentTemplateFactory, CrewAssessmentFactory, CrewAssessmentCreatorFactory, UserFactory,\r\n AssessmentSyncResultFactory, SettingsMain, PaxInfoFactory, MemoFactory, FaqFactory, GroundDutyFactory, MemoImagesFactory, AircaftPositionsFactory,\r\n AimsCrewMemosFactory, IncompleteServicesSourceFactory, LeaveRequestFactory, CourseFactory, CampaignFactory, CrewHotelFactory, LuggageComplianceFactory,\r\n ScheduleAcknowledgeFactory, CrewCallFactory, PreviousDutyFactory, LogCallFactory, CheckInFactory, PhiloxeniaQuestionsFactory, TimeLogFactory,\r\n FlightCheckInsFactory, AnnualLeavesFactory, FlightDelaysFactory, ToolkitFactory, CustomerEventFactory, ExpiriesFactory,\r\n TraineeCoursesDetailsFactory, RequestFactory, WifiAvailabilityFactory, FlightServiceEventsFactory, PassengerMealServiceFactory, GroomingCategoriesFactory) {\r\n\r\n\r\n /**\r\n * Find if a relative old flight exists and if exists update it \r\n * @memberof SyncAPIService\r\n * @param {object} oldflight\r\n * @param {array} flights\r\n * @return {boolean} hasRelativeFlight\r\n */\r\n function relativeFlightMatcher(oldflight, flights) {\r\n var relativeFlights = [];\r\n var found = false;\r\n\r\n for (var i = 0; i < flights.length; i++) {\r\n if (oldflight.FlightNo == flights[i].FlightNo && oldflight.FlightDate == flights[i].FlightDate && oldflight.Departure == flights[i].Departure) {\r\n relativeFlights.push(flights[i]);\r\n found = true;\r\n break;\r\n }\r\n }\r\n\r\n if (!found) {\r\n var flight = null;\r\n var oldFlightNo = null;\r\n var lastDigit = oldflight.FlightNo.substr(oldflight.FlightNo.length - 1, 1)\r\n\r\n oldFlightNo = (!isNaN(lastDigit)) ? oldflight.FlightNo : oldflight.FlightNo.substr(0, oldflight.FlightNo.length - 1);\r\n\r\n\r\n for (var i = 0; i < flights.length; i++) {\r\n lastDigit = flights[i].FlightNo.substr(flights[i].FlightNo.length - 1, 1);\r\n\r\n flight = (!isNaN(lastDigit)) ? flights[i].FlightNo : flights[i].FlightNo.substr(0, flights[i].FlightNo.length - 1);\r\n\r\n if (oldFlightNo == flight && oldflight.FlightDate == flights[i].FlightDate && oldflight.Departure == flights[i].Departure) {\r\n relativeFlights.push(flights[i]);\r\n }\r\n }\r\n }\r\n\r\n if (relativeFlights.length == 1) {\r\n var cabinReportLocalEdit = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(oldflight.FlightId);\r\n cabinReportLocalEdit.FlightAimsId = relativeFlights[0].FlightAimsId;\r\n cabinReportLocalEdit.FlightId = relativeFlights[0].FlightId;\r\n CabinReportLocalEditFactory.setCabinReportToStorage(cabinReportLocalEdit);\r\n\r\n return true;\r\n } else if (relativeFlights.length > 1) {\r\n for (var i = 1; i < relativeFlights.length; i++) {\r\n for (var j = 0; j < relativeFlights.length - i; j++) {\r\n if (relativeFlights[j].FlightNo > relativeFlights[j + 1].FlightNo) {\r\n var a = relativeFlights[j];\r\n relativeFlights[j] = relativeFlights[j + 1];\r\n relativeFlights[j + 1] = a;\r\n }\r\n }\r\n }\r\n\r\n var cabinReportLocalEdit = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(oldflight.FlightId);\r\n cabinReportLocalEdit.FlightAimsId = relativeFlights[0].FlightAimsId;\r\n cabinReportLocalEdit.FlightId = relativeFlights[0].FlightId;\r\n CabinReportLocalEditFactory.setCabinReportToStorage(cabinReportLocalEdit);\r\n\r\n return true;\r\n } else {\r\n return false;\r\n }\r\n };\r\n\r\n return {\r\n /**\r\n * Send and get the latest information \r\n * @memberof SyncAPIService\r\n * @param {object} aimsId\r\n * @param {array} memoIdsToSend \r\n */\r\n doSync: function (aimsId, memoIdsToSend) {\r\n //Clear timeLogs from local storage older than 2 days\r\n TimeLogFactory.cleanOldData();\r\n //clear CrewMeal ratings from local storage that have timestamp older than 20 days\r\n DataCleanerFactory.deleteOldCrewMealsRatings();\r\n // get the saved cabin reports\r\n var allSavedReports = CabinReportLocalEditFactory.getCabinReportsFromStorage();\r\n var IsAssessmentEnabled = SettingsMain.getIsAssessmentEnabled();\r\n var user = UserFactory.getUser();\r\n\r\n var lastLog = SyncLogFactory.getSyncLog();\r\n var lastSyncDate = lastLog.date;\r\n\r\n //Free to send all reports and assessments:\r\n var messagesToSend = MessageFactory.getUnsynchedReadMessages();\r\n\r\n // keep only the ones that are ready to be sent\r\n var reportsToSend = CabinReportSendToServerFactory.getCompletedListFromCabinReportLocalEdits(allSavedReports);\r\n var assessmentsToSend = [];\r\n if (IsAssessmentEnabled && user.position == 'SA') {\r\n assessmentsToSend = CrewAssessmentFactory.getAssementsReadyToSend();\r\n }\r\n\r\n var passengersCampaignsToSend = CampaignFactory.getPaxAssignmentsFromStorage();\r\n\r\n var luggageCompliance = {\r\n luggageComplianceReports: LuggageComplianceFactory.getLuggageComplianceFromStorage().filter(x => !x.isSynced)\r\n }\r\n\r\n //Get call requests made while offline\r\n var phoneCallLog = {\r\n CrewCallReports: LogCallFactory.getLogCallsFromStorage()\r\n }\r\n\r\n var oneStopShopEvents = CustomerEventFactory.getUnsyncedCustomerEvents();\r\n\r\n var syncData = {\r\n \"SyncCabinReports\": reportsToSend,\r\n \"Messages\": messagesToSend,\r\n \"Assessments\": assessmentsToSend,\r\n \"Memos\": memoIdsToSend,\r\n \"PassengersCampaigns\": passengersCampaignsToSend,\r\n \"LuggageCompliance\": luggageCompliance,\r\n \"CrewCallLog\" : phoneCallLog,\r\n \"LastSyncDate\": lastSyncDate,\r\n \"OneStopShopEvents\": oneStopShopEvents,\r\n \"LastSyncDate\": lastSyncDate\r\n };\r\n\r\n var call = $q.defer();\r\n $http.post(apiUrl + '/sync', syncData, {\r\n 'Content-Type': 'application/json'\r\n })\r\n .then(\r\n function (responseData) {\r\n\r\n if (responseData == undefined\r\n || responseData.data == undefined\r\n || responseData.data.data == undefined\r\n || responseData.data.data.SyncCabinData == undefined) {\r\n var err = new Error();\r\n err.status = -1;\r\n var msg = \"ResponseData error in sync :\" + JSON.stringify(responseData);\r\n\r\n LogService.debug(msg, err)\r\n call.reject(err);\r\n return;\r\n }\r\n var response = responseData.data.data;\r\n\r\n\r\n //keep flights, will be used to retain a flight for old unsynched reports\r\n var orgFlights = FlightFactory.getFlightsFromStorage();\r\n var IsAssessmentEnabled = response.SyncCabinData.IsAssessmentEnabled;\r\n\r\n SettingsMain.setIsAssessmentEnabled(IsAssessmentEnabled);\r\n\r\n //Save schedule changes dates \r\n ScheduleAcknowledgeFactory.setAllScheduleChangesToStorage(response.SyncCabinData.ScheduleChanges);\r\n if (response.SyncCabinData.CrewCallLog && response.SyncCabinData.CrewCallLog.ResponseSuccess) {\r\n LogCallFactory.cleanLogsFromStorage();\r\n }\r\n \r\n var oneStopShop = response.SyncCabinData.OneStopShop;\r\n\t\t\t\t\t\t\t//save toolkit items\r\n if(oneStopShop.ToolkitItems){\r\n ToolkitFactory.setToolkitItemsFromServer(oneStopShop.ToolkitItems);\r\n }\r\n\r\n\t\t\t\t\t\t\t//check OneStopShop CustomerEvents save status\r\n if(oneStopShop.CustomerEventsSynced){\r\n oneStopShop.CustomerEventsSynced.forEach(function(event){\r\n var localCustomerEvent = oneStopShopEvents.find(x => x.TemporaryId == event.TemporaryId);\r\n localCustomerEvent.Synced = event.SaveSuccess;\r\n \r\n //No Treatment Id reset value\r\n if(localCustomerEvent.TreatmentId == null)\r\n localCustomerEvent.TreatmentId = -1;\r\n \r\n CustomerEventFactory.updateCustomerEvent(localCustomerEvent);\r\n }); \r\n }\r\n\t\t\t\t\t\t\r\n\r\n //save training courses\r\n var rawTrainingCourses = response.SyncCabinData.TrainingCourses;\r\n var courses = [];\r\n\r\n rawTrainingCourses.forEach(function (course) {\r\n courses.push({\r\n Id: course.Id,\r\n Title: course.Title,\r\n HasLimitedInfo: true\r\n });\r\n });\r\n\r\n CourseFactory.setCoursesFromServer(courses);\r\n\r\n //clean crew member info\r\n var responseFlightIds = response.SyncCabinData.flights.map(x => x.FlightId);\r\n CrewCallFactory.cleanOldData(responseFlightIds);\r\n PreviousDutyFactory.cleanOldData(responseFlightIds);\r\n PhiloxeniaQuestionsFactory.cleanOldData(responseFlightIds);\r\n LuggageComplianceFactory.cleanOldData(responseFlightIds);\r\n AircaftPositionsFactory.cleanOldData(responseFlightIds);\r\n FlightCheckInsFactory.cleanOldData(responseFlightIds);\r\n\r\n //TODO::move to refresh service:\r\n //DataCleaner for the pax info (indexedDb)\r\n var pendingFlightIds = CabinReportLocalEditFactory.getFlightIdsWithPendingReports();\r\n PaxInfoFactory.cleanOldDataPaxInfo(pendingFlightIds);\r\n //Data cleaner for the campaigns\r\n CampaignFactory.cleanOldCampaigns(pendingFlightIds);\r\n // //Data cleaner for the aims crew memos\r\n // AimsCrewMemosFactory.cleanOldAimsCrewMemos();\r\n AimsCrewMemosFactory.clearAimsCrewMemosFactoryFromStorage();\r\n //Data cleaner for flight delays\r\n FlightDelaysFactory.cleanOldFlightDelays(responseFlightIds);\r\n //Clean old data for the flight service events\r\n FlightServiceEventsFactory.cleanOldDataServiceEvents(pendingFlightIds);\r\n\r\n GroomingCategoriesFactory.clearGroomingReportsFromStorage();\r\n\r\n //Data cleaner for the customer events (flightDate of the event >= today - 5 days)\r\n // CustomerEventHistoryFactory.deleteOldHistoryEvents();\r\n // CustomerEventFactory.deleteOldCustomerEvents();\r\n\r\n\r\n // keep old assessments\r\n var oldAssessments = CrewAssessmentFactory.getCrewAssessmentsFromStorage();\r\n\r\n // FlightGateFactory.processUpdatedData(response.SyncCabinData.flightGates);\r\n\r\n // clear existing server data\r\n DataCleanerFactory.deleteAllServerData();\r\n\r\n var fromSync = true;\r\n GroundDutyFactory.mergeGroundDutiesToStorage(response.SyncCabinData.groundDuties, fromSync);\r\n CrewRouteFactory.setCrewRoutesToStorage(response.SyncCabinData.CrewRoutes);\r\n CrewMealFactory.setCrewMealsToStorage(response.SyncCabinData.CateringCrewMeals);\r\n CrewHotelFactory.setCrewHotelsToStorage(response.SyncCabinData.CrewHotels);\r\n CheckInFactory.setCheckInInfoToStorage(response.CrewCheckInInfo);\r\n FlightServiceEventsFactory.setEventTypes(response. FlightServiceEventTypes);\r\n AnnualLeavesFactory.setAnnualLeavesToStorage(response.AnnualLeaves);\r\n ExpiriesFactory.setCrewExpiriesToStorage(response.CrewExpiries);\r\n AimsCrewMemosFactory.setAimsCrewMemosToStorage(response.SyncCabinData.aimsCrewMemos);\r\n WifiAvailabilityFactory.setRegistrationsToStorage(response.RegistrationsWithWifi);\r\n // PassengerMealServiceFactory.checkAndsetPassengerMealsServicesToStorage(response.PassengerMealServices);\r\n GroomingCategoriesFactory.setGroomingCategories(response.GroomingCategories);\r\n \r\n if(response.RosterRequestAncillaries){\r\n RequestFactory.setSubmissionDeadlineDateToStorage(response.RosterRequestAncillaries.SubmissionEndDate);\r\n }\r\n\r\n //save, update or add memos\r\n var memos = response.SyncCabinData.memos;\r\n MemoFactory.setMemosFromServer(memos, memoIdsToSend, lastSyncDate);\r\n\r\n LeaveRequestFactory.saveLeaveRequestInformation(response.SyncCabinData.LeaveRequestInformation);\r\n\r\n //delete leftover memos \r\n var serverMemoIds = response.SyncCabinData.memoIds;\r\n for (var i = 0; i < serverMemoIds.length; i++) {\r\n MemoFactory.deleteMemoFromStorage(serverMemoIds[i]);\r\n }\r\n for (var i = 0; i < memos.length; i++) {\r\n MemoImagesFactory.deleteMemoImageByMemoId(memos[i].Id);\r\n }\r\n var images = response.SyncCabinData.Images;\r\n MemoImagesFactory.setImagesToServer(images);\r\n for (var i = 0; i < serverMemoIds.length; i++) {\r\n MemoImagesFactory.deleteMemoImageByMemoId(serverMemoIds[i]);\r\n }\r\n // save flight data to local storage\r\n var flightData = response.SyncCabinData.flights;\r\n var flights = FlightFactory.markScheduleChangedFlights(flightData, orgFlights);\r\n var assessments = response.SyncCabinData.assessments;\r\n var cabinReports = response.SyncCabinData.cabinReports;\r\n var assessmentTemplate = response.SyncCabinData.assessmentTemplate;\r\n CrewAssessmentTemplateFactory.setCrewAssessmentTemplateToStorage(assessmentTemplate);\r\n var reportGuids = response.SyncCabinData.guids;\r\n ReportGuidFactory.setReportGuidsToStorage(reportGuids);\r\n\r\n // save cabin report template to storage\r\n var cabinReportTemplateItems = response.SyncCabinData.cabinReportTemplate;\r\n CabinReportTemplateItemFactory.setCabinReportTemplateItemsToStorage(cabinReportTemplateItems);\r\n\r\n //store and sync messages\r\n var messages = response.SyncCabinData.messages;\r\n MessageFactory.markReadAsSynched(messages);\r\n MessageFactory.storeMessagesFromServer(messages);\r\n\r\n // save aircraft types to local storage\r\n var aircraftTypes = response.SyncCabinData.aircraftTypes;\r\n AircraftTypeFactory.setAircraftTypesToStorage(aircraftTypes);\r\n\r\n // save water uplift actions to local storage\r\n var wuas = response.SyncCabinData.waterUpliftActions;\r\n WaterUpliftActionFactory.setWaterUpliftActionsToStorage(wuas);\r\n\r\n // save ac supplies to local storage\r\n var acSupplies = response.SyncCabinData.acSupplies;\r\n ACSupplyFactory.setACSuppliesToStorage(acSupplies);\r\n\r\n // save special meal sources to local storage\r\n var specialMealSources = response.SyncCabinData.specialMealSources;\r\n SpecialMealSourceFactory.setSpecialMealSourcesToStorage(specialMealSources);\r\n\r\n // save special meal types to local storage\r\n var specialMealTypes = response.SyncCabinData.specialMealTypes;\r\n SpecialMealTypeFactory.setSpecialMealTypesToStorage(specialMealTypes);\r\n\r\n // save currencies to local storage\r\n /*var currencies = response.SyncCabinData.currencies;\r\n CurrencyFactory.setCurrenciesToStorage(currencies);*/\r\n\r\n //save all FAQs to local storage\r\n var FAQs = response.SyncCabinData.FAQPairs;\r\n FaqFactory.setFAQsFromServer(FAQs);\r\n\r\n // save currencies to local storage\r\n var travelReasons = response.SyncCabinData.travelValueIncompleteReasons;\r\n TravelValueIncompleteReasonFactory.setReasonsToStorage(travelReasons);\r\n\r\n // save Incomplete In-Flight Services Reasons and Types:\r\n var incompleteInFlightServiceListOfValues = response.SyncCabinData.incompleteInFlightServiceListOfValues;\r\n IncompleteServicesSourceFactory.setIncompleteInFlightServiceListOfValues(incompleteInFlightServiceListOfValues);\r\n\r\n // log the sync user and date\r\n SyncLogFactory.setSyncLog(aimsId, response.SyncCabinData.version, response.SyncCabinData.toDate);\r\n\r\n // save ccms to local storage\r\n var ccms = response.SyncCabinData.ccms;\r\n\r\n CCMSFactory.setCCMSToStorage(ccms);\r\n\r\n var traineeCourses = response.SyncCabinData.TraineeCourses;\r\n TraineeCoursesDetailsFactory.setTraineeCoursesToStorage(traineeCourses);\r\n\r\n var traineeFlightCourses = response.SyncCabinData.TraineeFlightCourses;\r\n TraineeCoursesDetailsFactory.setTraineeFlightCoursesToStorage(traineeFlightCourses);\r\n\r\n // get the sync results\r\n var syncResults = CabinReportSyncResultFactory.fromObjectList(response.SyncCabinData.reportResults);\r\n var flight;\r\n // mark sent reports as synched\r\n for (var j = 0; j < reportsToSend.length; j++) {\r\n var syncResult = CabinReportSyncResultFactory.getSyncResult(syncResults, reportsToSend[j].ReportGuid);\r\n\r\n if (syncResult != null) {\r\n if (syncResult.success) {\r\n CabinReportLocalEditFactory.markReportAsSynched(reportsToSend[j].ReportGuid);\r\n syncResult.Result = 'Successfully submitted';\r\n } else {\r\n syncResult.Result = 'Submission error';\r\n }\r\n\r\n // find flight and append report fields\r\n flight = null;\r\n if (orgFlights != null) {\r\n for (i = 0; i < orgFlights.length; i++) {\r\n if ((orgFlights[i].FlightId != null && orgFlights[i].FlightId == reportsToSend[j].FlightId) || (orgFlights[i].FlightAimsId != null && orgFlights[i].FlightAimsId == reportsToSend[j].FlightAimsId)) {\r\n flight = orgFlights[i];\r\n break;\r\n }\r\n }\r\n }\r\n //var flight = FlightFactory.getFlightFromStorage(reportsToSend[j].FlightAimsId);\r\n\r\n if (flight != null) {\r\n syncResult.FlightAimsId = flight.FlightAimsId;\r\n syncResult.FlightId = flight.FlightId;\r\n syncResult.ScheduledDepartureDateUTC = flight.ScheduledDepartureDateUTC;\r\n syncResult.FlightNo = flight.FlightNo;\r\n syncResult.Departure = flight.Departure;\r\n syncResult.Arrival = flight.Arrival;\r\n syncResult.ScheduledDepartureTimeUTC = flight.ScheduledDepartureTimeUTC;\r\n syncResult.AcTailNo = flight.AcTailNo;\r\n }\r\n }\r\n }\r\n // save the sync results\r\n CabinReportSyncResultFactory.setCabinReportSyncResultsToStorage(syncResults);\r\n AssessmentSyncResultFactory.setAssessmentSyncResultsToStorage(response.SyncCabinData.assessmentResults)\r\n // delete local flights with no local reports\r\n DataCleanerFactory.deleteOrphanedLocalFlights();\r\n\r\n //**************** ADD CODE TO KEEP FLIGHTS IF THEY STIL HAVE AN NOT SYCNHED REPORT *********************//\r\n //find flight ids used by draft reports\r\n //**************** ADD CODE TO KEEP FLIGHTS IF THEY STIL HAVE AN NOT SYCNHED REPORT *********************//\r\n //find flight ids used by draft reports\r\n if (allSavedReports) {\r\n var verifyFlightAimsIds = [];\r\n var verifyFlightIds = [];\r\n for (var i = 0; i < allSavedReports.length; i++) {\r\n if (allSavedReports[i].Status == 'draft' || allSavedReports[i].Status == 'completed')\r\n verifyFlightAimsIds.push(allSavedReports[i].FlightAimsId);\r\n verifyFlightIds.push(allSavedReports[i].FlightId);\r\n }\r\n //search these ids into the newly received flights\r\n if (verifyFlightAimsIds.length > 0) {\r\n var missingIds = [];\r\n var missingAimsIds = [];\r\n var found, id, aimsId;\r\n for (var i = 0; i < verifyFlightAimsIds.length; i++) {\r\n found = false;\r\n aimsId = verifyFlightAimsIds[i];\r\n id = verifyFlightIds[i];\r\n for (var f = 0; f < flights.length; f++) {\r\n if ((flights[f].FlightId != null && flights[f].FlightId == id) || (flights[f].FlightAimsId != null && flights[f].FlightAimsId == aimsId)) {\r\n found = true;\r\n break;\r\n }\r\n }\r\n if (!found)\r\n missingIds.push(id);\r\n missingAimsIds.push(aimsId);\r\n }\r\n //search missing flights in flights stored before sync\r\n if (orgFlights) {\r\n for (var m = 0; m < missingIds.length; m++) {\r\n id = missingIds[m];\r\n aimsId = missingAimsIds[m];\r\n for (var o = 0; o < orgFlights.length; o++) {\r\n if ((orgFlights[o].FlightId != null && orgFlights[o].FlightId == id) || (orgFlights[o].FlightAimsId != null && orgFlights[o].FlightAimsId == aimsId)) {\r\n if (!relativeFlightMatcher(orgFlights[o], flights)) {\r\n flights.push(orgFlights[o]);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n /* //keep assessments when their route exists in flight\r\n CrewAssessmentFactory.storeAllSyncAssessments(orgAssessments,assessments,flights);*/\r\n\r\n FlightFactory.storeFlightsWithReportsAndMessages(flights, cabinReports, messages);\r\n //Keep the old assessment and create assessment to the routes that are left\r\n var assessmentsToCreate = [];\r\n var finalAssessments = [];\r\n assessments = (assessments) ? assessments : [];\r\n for (var i = 0; i < assessments.length; i++) {\r\n var isExists = false;\r\n for (var j = 0; j < oldAssessments.length; j++) {\r\n if (oldAssessments[j].Route == assessments[i].Route && oldAssessments[j].DutyDate == assessments[i].DutyDate) {\r\n var oldAssessment = CrewAssessmentFactory.updateCrewAssessment(oldAssessments[j], assessments[i]);\r\n\r\n finalAssessments.push(oldAssessment);\r\n isExists = true;\r\n break;\r\n }\r\n }\r\n\r\n\r\n\r\n if (!isExists) {\r\n assessmentsToCreate.push(assessments[i]);\r\n }\r\n }\r\n\r\n //keep assessment for old reports\r\n for (var i = 0; i < oldAssessments.length; i++) {\r\n var IsAssessmentExists = false;\r\n for (var j = 0; j < finalAssessments.length; j++) {\r\n if (oldAssessments[i].Id == finalAssessments[j].Id) {\r\n IsAssessmentExists = true;\r\n break;\r\n }\r\n }\r\n if (!IsAssessmentExists) {\r\n if (CabinReportLocalEditFactory.IsExistForRouteDutyDate(oldAssessments[i].Route, oldAssessments[i].DutyDate)) {\r\n finalAssessments.push(oldAssessments[i]);\r\n }\r\n\r\n }\r\n }\r\n var newAssessments = CrewAssessmentCreatorFactory.createCrewAssessments(assessmentsToCreate);\r\n\r\n finalAssessments = finalAssessments.concat(newAssessments);\r\n CrewAssessmentFactory.setCrewAssessmentsToStorage(finalAssessments);\r\n CrewAssessmentFactory.storeFlightsWithAssessments();\r\n CrewAssessmentFactory.storeCrewRoutesWithAssessments();\r\n\r\n\r\n //TimeLogFactory.timeLogToStorage(timeLog, response.SyncCabinData.timelog);\r\n\r\n // return true\r\n call.resolve(responseData);\r\n },\r\n function (err) {\r\n call.reject(err);\r\n }\r\n );\r\n return call.promise;\r\n },\r\n /**\r\n * Update local reports from synced Fligths \r\n * @memberof SyncAPIService\r\n */\r\n updateCabinReportLocalEditFromSynch: function () {\r\n var cabinReportLocalEdits = CabinReportLocalEditFactory.getCabinReportsFromStorage();\r\n if (cabinReportLocalEdits != undefined && cabinReportLocalEdits != null) {\r\n for (var i = 0; i < cabinReportLocalEdits.length; i++) {\r\n var flight = FlightFactory.getFlightFromStorage(cabinReportLocalEdits[i].FlightId, cabinReportLocalEdits[i].FlightAimsId);\r\n if ((cabinReportLocalEdits[i].Status == \"draft\" || cabinReportLocalEdits[i].Status == \"completed\") && (flight)) {\r\n\r\n //console.log(cabinReportLocalEdits[i].FlightAimsId);\r\n cabinReportLocalEdits[i].Departure = flight.Departure;\r\n cabinReportLocalEdits[i].Arrival = flight.Arrival;\r\n cabinReportLocalEdits[i].AcType = flight.AcType;\r\n cabinReportLocalEdits[i].AcTailNo = flight.AcTailNo;\r\n cabinReportLocalEdits[i].FlightNo = flight.FlightNo;\r\n cabinReportLocalEdits[i].DepartureICAO = flight.DepartureICAO;\r\n cabinReportLocalEdits[i].DepartureCountry = flight.DepartureCountry;\r\n cabinReportLocalEdits[i].DepartureName = flight.DepartureName;\r\n cabinReportLocalEdits[i].ArrivalICAO = flight.ArrivalICAO;\r\n cabinReportLocalEdits[i].ArrivalCountry = flight.ArrivalCountry;\r\n cabinReportLocalEdits[i].ArrivalName = flight.ArrivalName;\r\n cabinReportLocalEdits[i].ScheduledDepartureDateUTC = flight.ScheduledDepartureDateUTC;\r\n cabinReportLocalEdits[i].ScheduledDepartureTimeUTC = flight.ScheduledDepartureTimeUTC;\r\n cabinReportLocalEdits[i].ScheduledDeparture = flight.ScheduledDeparture;\r\n cabinReportLocalEdits[i].BookedC = flight.BookedC;\r\n cabinReportLocalEdits[i].BookedY = flight.BookedY;\r\n cabinReportLocalEdits[i].BookedInf = flight.BookedInf;\r\n cabinReportLocalEdits[i].BookedPad = flight.BookedPad;\r\n cabinReportLocalEdits[i].BookedChld = flight.BookedChld;\r\n cabinReportLocalEdits[i].ActualC = flight.ActualC;\r\n cabinReportLocalEdits[i].ActualY = flight.ActualY;\r\n cabinReportLocalEdits[i].ActualInf = flight.ActualInf;\r\n cabinReportLocalEdits[i].ActualPad = flight.ActualPad;\r\n cabinReportLocalEdits[i].ActualChld = flight.ActualChld;\r\n\r\n cabinReportLocalEdits[i].DepartureGate = flight.DepartureGate;\r\n cabinReportLocalEdits[i].DepartureTimezone = flight.DepartureTimezone;\r\n cabinReportLocalEdits[i].ArrivalTimezone = flight.ArrivalTimezone;\r\n cabinReportLocalEdits[i].CallSign = flight.CallSign;\r\n cabinReportLocalEdits[i].ScheduledArrival = flight.ScheduledArrival;\r\n cabinReportLocalEdits[i].Route = flight.Route;\r\n cabinReportLocalEdits[i].DutyDate = flight.DutyDate;\r\n\r\n var manualCCMSCrewPositions = []\r\n for (var k = 0; k < cabinReportLocalEdits[i].CCMSCrewPositions.length; k++) {\r\n if (cabinReportLocalEdits[i].CCMSCrewPositions[k].IsManual) {\r\n manualCCMSCrewPositions.push(cabinReportLocalEdits[i].CCMSCrewPositions[k]);\r\n }\r\n }\r\n\r\n cabinReportLocalEdits[i].crew = flight.crew;\r\n var newCCMSCrewPositions = [];\r\n var IsNew;\r\n var changeStatus = false;\r\n\r\n for (var h = 0; h < cabinReportLocalEdits[i].crew.length; h++) {\r\n if ((cabinReportLocalEdits[i].crew[h].isDHC == false) &&\r\n (cabinReportLocalEdits[i].crew[h].position != 'CP') &&\r\n (cabinReportLocalEdits[i].crew[h].position != 'FO')) {\r\n var crewPosition = CCMSCrewPositionFactory.createNew();\r\n crewPosition.CrewId = cabinReportLocalEdits[i].crew[h].aimsId;\r\n crewPosition.Initials = cabinReportLocalEdits[i].crew[h].shortname;\r\n crewPosition.Name = cabinReportLocalEdits[i].crew[h].name;\r\n crewPosition.Position = cabinReportLocalEdits[i].crew[h].position;\r\n crewPosition.IsManual = false;\r\n IsNew = false;\r\n for (var k = 0; k < cabinReportLocalEdits[i].CCMSCrewPositions.length; k++) {\r\n if (flight.crew[h].aimsId == cabinReportLocalEdits[i].CCMSCrewPositions[k].CrewId) {\r\n crewPosition.CCMS = cabinReportLocalEdits[i].CCMSCrewPositions[k].CCMS;\r\n crewPosition.CrewComments = cabinReportLocalEdits[i].CCMSCrewPositions[k].CrewComments;\r\n crewPosition.AdditionalFeedbackId = cabinReportLocalEdits[i].CCMSCrewPositions[k].AdditionalFeedbackId;\r\n crewPosition.Route = cabinReportLocalEdits[i].Route;\r\n if (crewPosition.CCMS == null) {\r\n IsNew = true;\r\n }\r\n break;\r\n }\r\n }\r\n if (IsNew) {\r\n changeStatus = true;\r\n }\r\n newCCMSCrewPositions.push(crewPosition);\r\n }\r\n }\r\n if (changeStatus) {\r\n cabinReportLocalEdits[i].Status = \"draft\";\r\n }\r\n cabinReportLocalEdits[i].CCMSCrewPositions = newCCMSCrewPositions.concat(manualCCMSCrewPositions);\r\n\r\n }\r\n }\r\n\r\n CabinReportLocalEditFactory.setCabinReportsToStorage(cabinReportLocalEdits);\r\n }\r\n }\r\n };\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('SynchCtrl', SynchCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SynchCtrl\r\n * @description \r\n * Manage Sync View\r\n * @ngInject\r\n */\r\n function SynchCtrl($scope, $uibModalInstance, UserFactory, CabinReportLocalEditFactory, SyncAPIService, \r\n SyncLogFactory, ReportGuidFactory, CabinReportSyncResultFactory, DataCleanerFactory, MessageFactory, \r\n CrewAssessmentFactory, AssessmentSyncResultFactory, SettingsMain, $route, $timeout, MemoFactory, \r\n FlightFactory, CabinReportRestoreFactory, CampaignFactory, LuggageComplianceFactory) {\r\n\r\n var IsAssessmentEnabled = SettingsMain.getIsAssessmentEnabled();\r\n var user = UserFactory.getUser();\r\n var lastLog = SyncLogFactory.getSyncLog();\r\n\r\n var reportstobesynched = CabinReportLocalEditFactory.getCabinReportLocalEditThatNeedToBeSynched();\r\n if (user.position == 'SA') {\r\n if (IsAssessmentEnabled) {\r\n var isSA = true;\r\n var assessmentstobesynched = CrewAssessmentFactory.getAssementsReadyToSend();\r\n }\r\n } else {\r\n var isSA = false;\r\n var assessmentstobesynched = [];\r\n }\r\n\r\n $scope.syncResultsVisible = false;\r\n $scope.isSynching = false;\r\n // setup the grid\r\n $scope.syncTableData = reportstobesynched;\r\n $scope.IsSA = isSA;\r\n // get the last sync date\r\n $scope.isFirstSync = false;\r\n $scope.isTooOldSync = false;\r\n $scope.lastSyncDate = '-';\r\n $scope.syncVersion = '1.2';\r\n // get the report credits\r\n $scope.reportCredits = ReportGuidFactory.getRemainingReportGuids();\r\n // display the number of reports to synch\r\n $scope.number_of_reports_to_sync = $scope.syncTableData.length;\r\n $scope.syncAssessmentTableData = CrewAssessmentFactory.getAssementsReadyToSend();\r\n $scope.number_of_assessments_to_sync = $scope.syncAssessmentTableData.length;\r\n\r\n\r\n if (lastLog == null) {\r\n $scope.isFirstSync = true;\r\n } else {\r\n if (lastLog.date != null) {\r\n $scope.lastSyncDate = new Date(lastLog.date).toUTC().toString('dd-MM-yyyy HH:mm') + ' UTC';\r\n if (Date.today().add(-3).days().toUTC().isAfter(new Date(lastLog.date).toUTC()))\r\n $scope.isTooOldSync = true;\r\n }\r\n\r\n if (lastLog.version != null)\r\n $scope.syncVersion = lastLog.version;\r\n }\r\n\r\n $scope.doSynch = doSynch;\r\n\r\n $scope.ok = ok;\r\n\r\n $scope.cancel = cancel;\r\n\r\n $scope.showReportSyncResults = showReportSyncResults;\r\n\r\n $scope.showAssessmentSyncResults = showAssessmentSyncResults;\r\n\r\n $scope.syncResultsOk = syncResultsOk;\r\n\r\n $scope.showSynchError = showSynchError;\r\n\r\n /**\r\n * Start Synch functionality\r\n * @memberof SynchCtrl\r\n */\r\n function doSynch() {\r\n\r\n //Save reports to indexedDB before the sync\r\n CabinReportRestoreFactory.backUpReports();\r\n\r\n //waiting for memoIds before we sync\r\n MemoFactory.getStoredMemosIds(function (memoIdsToSend) {\r\n // get the user\r\n var user = UserFactory.getUser();\r\n\r\n // call the remote service for data\r\n var q = SyncAPIService.doSync(user.aimsId, memoIdsToSend);\r\n $scope.isSynching = true;\r\n\r\n q.then(function (response) {\r\n $scope.isSynching = false;\r\n if ($scope.number_of_reports_to_sync > 0) {\r\n $scope.showReportSyncResults('synched');\r\n } else {\r\n $scope.showReportSyncResults('synched-no-send');\r\n }\r\n $scope.showAssessmentSyncResults();\r\n DataCleanerFactory.deleteSynchedLocalCabinReports();\r\n DataCleanerFactory.deleteOrphanedLocalReports();\r\n DataCleanerFactory.deleteOrphanedCustomerEvents();\r\n SyncAPIService.updateCabinReportLocalEditFromSynch();\r\n FlightFactory.initializeFlights();\r\n MemoFactory.markGroundDutiesUnread();\r\n $scope.campaigns = CampaignFactory.syncResultFormat(response.data.data.SyncCabinData.Campaigns);\r\n \r\n $scope.luggageCompliance = LuggageComplianceFactory.syncResultFormat(response.data.data.SyncCabinData.LuggageCompliance);\r\n });\r\n\r\n q.catch(function (err) {\r\n $scope.isSynching = false;\r\n\r\n if (err.status == -1) {\r\n $scope.errorName = \"There were problems during the server synchronization. Please try again.\";\r\n } else if (err.status != 401) {\r\n // if an error was encountered display an error message\r\n $scope.errorName = \"Could not reach the remote server. Please connect to the Internet and try again.\";\r\n } else {\r\n $uibModalInstance.close('');\r\n }\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * show Report Sync Results\r\n * @memberof SynchCtrl\r\n */\r\n function showReportSyncResults() {\r\n $scope.syncResultsVisible = true;\r\n // get the sync results\r\n $scope.syncResultsTableData = CabinReportSyncResultFactory.getCabinReportSyncResultsFromStorage();\r\n $scope.syncSuccesses = CabinReportSyncResultFactory.getSuccesses($scope.syncResultsTableData);\r\n $scope.syncFailures = CabinReportSyncResultFactory.getFailures($scope.syncResultsTableData);\r\n\r\n if ($scope.syncResultsTableData != null) {\r\n $scope.reports_to_sync = $scope.syncResultsTableData.length;\r\n } else {\r\n $scope.reports_to_sync = 0;\r\n }\r\n\r\n if ($scope.syncSuccesses == 1) {\r\n $scope.sync_successes_descr = 'Cabin Report was';\r\n } else {\r\n $scope.sync_successes_descr = 'Cabin Reports were';\r\n }\r\n\r\n if ($scope.syncFailures == 1) {\r\n $scope.sync_failures_descr = 'Cabin Report was';\r\n } else {\r\n $scope.sync_failures_descr = 'Cabin Reports were';\r\n }\r\n $scope.unreadMessages = MessageFactory.getCountOfUnreadMessages();\r\n }\r\n\r\n /**\r\n * show Assessment Sync Results\r\n * @memberof SynchCtrl\r\n */\r\n function showAssessmentSyncResults() {\r\n $scope.syncResultsVisible = true;\r\n // get the sync results\r\n $scope.syncAssessmentResultsTableData = AssessmentSyncResultFactory.getAssessmentSyncResultsFromStorage();\r\n $scope.syncAssessmentSuccesses = AssessmentSyncResultFactory.getSuccesses($scope.syncAssessmentResultsTableData);\r\n $scope.syncAssessmentFailures = AssessmentSyncResultFactory.getFailures($scope.syncAssessmentResultsTableData);\r\n\r\n\r\n if ($scope.syncAssessmentResultsTableData != null) {\r\n $scope.assessments_to_sync = $scope.syncAssessmentResultsTableData.length;\r\n } else {\r\n $scope.assessments_to_sync = 0;\r\n }\r\n\r\n if ($scope.syncAssessmentSuccesses == 1) {\r\n $scope.sync_assessment_successes_descr = 'Crew Feedback was';\r\n } else {\r\n $scope.sync_assessment_successes_descr = 'Crew Feedbacks were';\r\n }\r\n\r\n if ($scope.syncAssessmentFailures == 1) {\r\n $scope.sync_assessment_failures_descr = 'Crew Feedbacks was';\r\n } else {\r\n $scope.sync_assessment_failures_descr = 'Crew Feedbacks were';\r\n }\r\n }\r\n\r\n /**\r\n * Close sync Result modal and update cache.\r\n * @memberof SynchCtrl\r\n */\r\n function syncResultsOk() {\r\n $uibModalInstance.close('synched');\r\n $route.reload();\r\n // get cache\r\n }\r\n\r\n /**\r\n * Show submision sync error\r\n * @memberof SynchCtrl\r\n */\r\n function showSynchError(message) {\r\n bootbox.dialog({\r\n message: message,\r\n title: \"Submission error\",\r\n buttons: {\r\n cancel: {\r\n label: \"OK\",\r\n className: \"btn-default\",\r\n callback: function () { }\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Close modal and update cache.\r\n * @memberof SynchCtrl\r\n */\r\n function cancel() {\r\n $uibModalInstance.close('cancel');\r\n // get cache\r\n }\r\n\r\n /**\r\n * Close modal\r\n * @memberof SynchCtrl\r\n */\r\n function ok() {\r\n $uibModalInstance.close('');\r\n }\r\n\r\n }\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('SyncLogFactory', SyncLogFactory);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SyncLogFactory\r\n * @description \r\n * Add, update or delete synchronization log\r\n * @ngInject\r\n */ \r\nfunction SyncLogFactory($log, GenericService) {\r\n\r\n /**\r\n * Initialize the Sync Log\r\n * @memberof SyncLogFactory\r\n */\r\n function SyncLog() {\r\n\t\t\tvar self = this;\r\n\t\t\tthis.userAimsId = null;\r\n\t\t\tthis.date = null;\r\n\t\t\tthis.version = null;\r\n\t\t\tthis.lastShow = null;\r\n\t\t\tthis.isUpdated = false;\r\n\t\t\tthis.lastScheduleDate = null;\r\n\t\t\tthis.forceSync = false;\r\n\t\t\t//showing the sync dialog\r\n\t\t\tthis.canShowSync = function() {\r\n\t\t\t\tvar can = false;\r\n\t\t\t\tif (this.lastShow == null)\r\n\t\t\t\t\tcan = true;\r\n\t\t\t\telse if ((new Date()).add(-10).minutes().toUTC().isAfter(new Date(this.lastShow).toUTC())) {\r\n\t\t\t\t\tcan = true;\r\n\t\t\t\t}\r\n\t\t\t\treturn can;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tvar objType = 'syncLog';\r\n\t\tvar objCallback = SyncLog; \r\n\t\t\t\r\n\t\tvar service = {\r\n\t\t\tgetSyncLog : getSyncLog,\r\n\t\t\tsetSyncLog : setSyncLog,\r\n\t\t\tupdateSyncVersion : updateSyncVersion,\r\n\t\t\tsetLastShow : setLastShow,\r\n\t\t\tclearSyncLog : clearSyncLog,\r\n getLastScheduleDate : getLastScheduleDate,\r\n\t\t\tsetLastScheduleDate : setLastScheduleDate,\r\n\t\t\tforceSync : forceSync\r\n\t\t}\r\n\t\r\n /**\r\n * Get Sync Log\r\n * @memberof SyncLogFactory\r\n * @return {object} syncLog \r\n */\r\n\t\tfunction getSyncLog() {\r\n\t\t\treturn GenericService.getOne(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Set Sync Log\r\n * @memberof SyncLogFactory\r\n * @param {string} userAimsId \r\n * @param {string} version \r\n * @param {string} lastScheduleDate \r\n */\r\n\t\tfunction setSyncLog(userAimsId, version, lastScheduleDate) {\r\n\t\t\tvar newLog = new SyncLog();\r\n\t\t\tnewLog.userAimsId = userAimsId;\r\n\t\t\tnewLog.date = new Date();\r\n\t\t\tnewLog.version = version;\r\n\t\t\tnewLog.lastShow = new Date();\r\n\t\t\tnewLog.isUpdated = false;\r\n\t\t\tnewLog.forceSync = false;\r\n newLog.lastScheduleDate = new Date(lastScheduleDate).getTime();\r\n\t\t\tGenericService.saveOne(newLog,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Update Sync Log version\r\n * @memberof SyncLogFactory\r\n * @param {string} version \r\n */\r\n\t\tfunction updateSyncVersion(version) {\r\n\r\n\t\t\tvar syncLog = SyncLog.getSyncLog();\r\n\r\n\t\t\tsyncLog.version = version;\r\n\t\t\tsyncLog.isUpdated = true;\r\n\r\n\r\n\t\t\tGenericService.saveOne(syncLog,objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Set last show of molal\r\n * @memberof SyncLogFactory\r\n */\r\n\t\tfunction setLastShow() {\r\n\t\t\tvar log = getSyncLog();\r\n\t\t\tif (log == null) log = new SyncLog();\r\n\t\t\tlog.lastShow = new Date();\r\n\r\n\t\t\tGenericService.saveOne(log,objType,objCallback);\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Clear Sync Log\r\n * @memberof SyncLogFactory\r\n */\r\n\t\tfunction clearSyncLog() {\r\n\t\t\tGenericService.removeAll(objType,objCallback);\r\n\t\t}\r\n \r\n /**\r\n * Get Last Schedule Date\r\n * @memberof SyncLogFactory\r\n * @return {string} date \r\n */\r\n function getLastScheduleDate() {\r\n var syncLog = getSyncLog();\r\n if (syncLog == null){\r\n return null;\r\n }else{ \r\n\t\t\t return syncLog.lastScheduleDate;\r\n }\r\n\t\t}\r\n\r\n /**\r\n * Set Last Schedule Date\r\n * @memberof SyncLogFactory\r\n * @param {string} date \r\n */\r\n\t\tfunction setLastScheduleDate(date) {\r\n var log = getSyncLog();\r\n\t\t\tif (log == null) log = new SyncLog();\r\n\t\t\tlog.lastScheduleDate = date;\r\n\r\n\t\t\tGenericService.saveOne(log,objType,objCallback);\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Forces Sync Modal to appear\r\n\t\t * @memberof SyncLogFactory\r\n\t\t */\r\n\t\tfunction forceSync(){\r\n\t\t\tvar syncLog = getSyncLog();\r\n\t\t\tsyncLog.forceSync = true;\r\n\t\t\tGenericService.saveOne(syncLog,objType,objCallback);\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('TicketCtrl', TicketCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name TicketCtrl\r\n * @description \r\n * Send a ticket\r\n * @ngInject\r\n */\r\nfunction TicketCtrl($scope,UserFactory, PhotoFactory, TicketAPIService,$location,$uibModal, version,CabinReportRestoreFactory) {\r\n \r\n var user = UserFactory.getUser();\r\n user\r\n $scope.submitted = false;\r\n $scope.ticket = {};\r\n $scope.ticket.photos = [];\r\n $scope.maximumAttatchedPhotos = 3;\r\n $scope.showMaxImages = false;\r\n $scope.quality = 0.6;\r\n $scope.width = 1280;\r\n $scope.height = 1024;\r\n $scope.sizeLimitKb = 1000;\r\n $scope.imageTooLargeMsg = false;\r\n $scope.gotoHome = gotoHome;\r\n $scope.state = 'ticket';\r\n $scope.restoreReportsAction = restoreReportsAction;\r\n appendPhoto();\r\n\r\n $scope.sendTicket = sendTicket;\r\n $scope.imageUploaded = imageUploaded;\r\n $scope.removePhoto = removePhoto;\r\n $scope.ticket.Version = version;\r\n \r\n if(user && user.aimsId && UserFactory.isLoggedIn()){\r\n $scope.ticket.aimsId = user.aimsId\r\n $scope.isLogged = true;\r\n }\r\n \r\n /**\r\n * Redirects to home view\r\n * @memberof TicketCtrl\r\n */\r\n function gotoHome(){\r\n $location.path(\"/\");\r\n }\r\n \r\n /**\r\n * Send application ticket information\r\n * @memberof TicketCtrl\r\n */\r\n function sendTicket(){\r\n $scope.submitted = true;\r\n if (validateTicket()){\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Dialogs/dlgTicketSend.html',\r\n controller: 'TicketModalCtrl',\r\n size: 'md',\r\n backdrop: 'static',\r\n keyboard: false,\r\n resolve: {\r\n ticket: function() {\r\n return $scope.ticket;\r\n },\r\n }\r\n })\r\n\r\n modalInstance.result.then(function() {\r\n $location.path(\"/\"); \r\n });\r\n }\r\n \r\n }\r\n \r\n \r\n /**\r\n * Validate ticket before sending\r\n * @memberof TicketCtrl\r\n * @return {boolean} isValid\r\n */\r\n function validateTicket(){\r\n var isValid = false;\r\n \r\n if ($scope.ticket.aimsId && $scope.ticket.title && $scope.ticket.description){\r\n isValid = true;\r\n }\r\n \r\n return isValid;\r\n }\r\n \r\n /**\r\n * is Image Too Large \r\n * @memberof TicketCtrl\r\n * @return {boolean} isValid\r\n */\r\n function isImageTooLarge(image) {\r\n var isLarge= false;\r\n if (image && image.dataURL != null) {\r\n isLarge = (image.dataURL.length > $scope.sizeLimitKb * 1024);\r\n }\r\n return isLarge;\r\n }\r\n\r\n /**\r\n * Upload Image\r\n * @memberof TicketCtrl\r\n */\r\n function imageUploaded(data,img) {\r\n //console.log('told of a new image', imageResult, this.imageBrowsed, $scope.imageBrowsed);\r\n var imageResult = data; //$scope.imageBrowsed;\r\n if (imageResult != null) {\r\n if(isImageTooLarge(data)){\r\n $scope.imageTooLargeMsg = true;\r\n }else{\r\n $scope.imageTooLargeMsg = false;\r\n img.PhotoData = imageResult.dataURL;\r\n img.FileType = imageResult.fileType || imageResult.file.type;\r\n img.Remarks = imageResult.fileName;\r\n appendPhoto();\r\n }\r\n\r\n }\r\n }\r\n \r\n /**\r\n * Allows to add more photos up to the maximum number allowed\r\n * @memberof TicketCtrl\r\n */\r\n function appendPhoto(){\r\n if($scope.ticket.photos.length< $scope.maximumAttatchedPhotos){\r\n var photo = PhotoFactory.createNew();\r\n $scope.ticket.photos.push(photo);\r\n }else{\r\n $scope.showMaxImages = true;\r\n }\r\n }\r\n \r\n /**\r\n * Remove Selected photo\r\n * @memberof TicketCtrl\r\n * @param {object} photo\r\n */\r\n function removePhoto(photo){\r\n PhotoFactory.deleteFromList(photo, $scope.ticket.photos);\r\n if($scope.showMaxImages){\r\n appendPhoto();\r\n }\r\n $scope.showMaxImages = false;\r\n\r\n }\r\n \r\n /**\r\n * Restore lost reports process and return list of FlightNo for each restored report into a modal.\r\n * @memberof flightFooter \r\n */\r\n function restoreReportsAction() {\r\n CabinReportRestoreFactory.restoreReports( function (restoreResults){\r\n var bootboxMessage = \"\";\r\n if(restoreResults != 'undefined' && restoreResults.length > 0){\r\n bootboxMessage = \"

Lost reports have been restored successfully for the following flights:

\";\r\n restoreResults.forEach(function (x) {\r\n bootboxMessage += \"
\";\r\n bootboxMessage += \"- \" + x;\r\n }); \r\n }\r\n else{\r\n bootboxMessage = \"No missing reports have been found\";\r\n }\r\n\r\n bootbox.alert({\r\n title: \"Retrieve lost reports\",\r\n message: bootboxMessage\r\n });\r\n });\r\n }\r\n\r\n}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.service(\"TicketAPIService\", TicketAPIService);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc service\r\n * @name TicketAPIService\r\n * @description \r\n * Manages the api calls for the Ticket report system\r\n * @ngInject\r\n */\r\nfunction TicketAPIService($http, $q, apiUrl, localStorageMD5Service, LogService) {\r\n /**\r\n * Send Ticket2\r\n * @memberof TicketAPIService\r\n * @return {object} promise\r\n */\r\n function sendTicket(ticket) {\r\n var call = $q.defer();\r\n \r\n ticket.DeviceData = getStoredValues();\r\n $http.post(apiUrl +'/ticket', ticket, {'Content-Type': 'application/json'})\r\n .then(\r\n function(responseData) {\r\n\r\n if(responseData==undefined || responseData.data==undefined || responseData.data.data==undefined) {\r\n var err=new Error();\r\n err.status=-1;\r\n var msg= \"ResponseData error while sending a ticket :\" + JSON.stringify(responseData);\r\n LogService.debug(msg,err)\r\n call.reject(err);\r\n }else{\r\n // return true\r\n call.resolve(responseData);\r\n }\r\n\r\n },\r\n function(err) {\r\n call.reject(err);\r\n }\r\n );\r\n return call.promise;\r\n }\r\n \r\n \r\n /**\r\n * Get all values from localstorage\r\n * @memberof TicketAPIService\r\n */\r\n function getStoredValues() {\r\n var values = [];\r\n var keys = localStorageMD5Service.keys();\r\n if (keys) {\r\n var key, value, sizeActual, error;\r\n for (var i = 0; i < keys.length; i++) {\r\n key = keys[i];\r\n try {\r\n value = localStorageMD5Service.get(key);\r\n value = angular.toJson(value);\r\n sizeActual = localStorageMD5Service.usedSize(key);\r\n error = null;\r\n } catch (e) {\r\n error = e.message || e.errorMessage;\r\n }\r\n values.push({\r\n key: key,\r\n value: value,\r\n error: error,\r\n size: (value) ? value.length : 0,\r\n sizeActual: sizeActual\r\n });\r\n }\r\n }\r\n return values;\r\n\r\n }\r\n\r\n return {\r\n sendTicket: sendTicket\r\n }; \r\n}\r\n \r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('TicketModalCtrl', TicketModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name TicketCtrl\r\n * @description \r\n * Report a bug of the application\r\n * @ngInject\r\n */\r\nfunction TicketModalCtrl($scope, $uibModalInstance, $timeout, TicketAPIService, LogService, PhotoFactory, ticket) {\r\n $scope.successful = false;\r\n $scope.error = false;\r\n\r\n\t\tvar q = TicketAPIService.sendTicket(ticket);\r\n\r\n q.then(function(responseData){\r\n\t\t\tif(responseData.data.data){\r\n $scope.successful = true;\r\n\t\t\t}\r\n\t\t\telse {\r\n $scope.error = true;\r\n\t\t\t}\r\n $timeout(function() {\r\n\t\t\t\t\t$uibModalInstance.close();\r\n }, 3000);\r\n\t\t},\r\n\t\tfunction(){\r\n $scope.error = true;\r\n $timeout(function() {\r\n\t\t\t\t\t$uibModalInstance.close();\r\n }, 3000);\r\n\t\t});\r\n}\r\n \r\n \r\n})();\r\n ","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('additionalTrainingReadOnly', additionalTrainingReadOnly);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name additionalTrainingReadOnly\r\n * @restrict E\r\n * @description\r\n * Implementation of additional Training ReadOnly\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function additionalTrainingReadOnly() {\r\n function link(scope, element, attrs) {\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: true,\r\n templateUrl: 'views/TrainingReadOnly/additional-training-read-only.tpl.html',\r\n scope: { traineeSession: \"=\" },\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('competencesReadOnly', competencesReadOnly);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name competencesReadOnly\r\n * @restrict E\r\n * @description\r\n * Implementation of competences read only\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function competencesReadOnly() {\r\n function link(scope, element, attrs) {\r\n if(scope.trainee.Competences){\r\n scope.trainee.Competences.forEach(function (competence) {\r\n competence.hasSelectedSubCompetence = competence.SubCompetences.some(x => x.Selected);\r\n }); \r\n }\r\n \r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/TrainingReadOnly/competences-read-only.tpl.html',\r\n scope: {trainee : \"=\"},\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n\r\n a3_cabin_reports.directive('courseReadOnly', courseReadOnly);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name courseReadOnly\r\n * @restrict E\r\n * @description\r\n * Initialize read only view of what was submitted\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n\r\n function courseReadOnly() {\r\n function link(scope) {\r\n scope.leftScroll = leftScroll;\r\n scope.rightScroll = rightScroll;\r\n scope.selectedTraineeSession = selectedTraineeSession;\r\n scope.selected = false;\r\n scope.selectedAbsentTraineeSession = selectedAbsentTraineeSession;\r\n \r\n scope.selectedPhase = scope.phases.find(x => x.PhaseId == scope.session.PhaseId);\r\n\r\n scope.selectedTraineeBadge = {\r\n crewId: scope.session.TraineesSessions[0].CrewId\r\n }; \r\n\r\n function leftScroll() {\r\n document.querySelector('.horizontal-scroll').scrollLeft -= 500;\r\n }\r\n \r\n function rightScroll() {\r\n document.querySelector('.horizontal-scroll').scrollLeft += 500;\r\n } \r\n\r\n \r\n function selectedTraineeSession() { \r\n return function( traineeSession ) {\r\n var showSession = false;\r\n if (traineeSession.CrewId === scope.selectedTraineeBadge.crewId){\r\n showSession = true;\r\n }\r\n return showSession;\r\n };\r\n }\r\n\r\n function selectedAbsentTraineeSession() { \r\n return function( traineeSession ) {\r\n var showPanel = false;\r\n if (traineeSession.CrewId === scope.selectedTraineeBadge.crewId && traineeSession.Items.length == 0){\r\n showPanel = true;\r\n }\r\n return showPanel;\r\n };\r\n }\r\n \r\n }\r\n return {\r\n restrict: 'E',\r\n templateUrl: \"views/TrainingReadOnly/course-read-only.tpl.html\",\r\n scope : { phases:\"=\", session:\"=\"},\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('gradingReadOnly', gradingReadOnly);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name gradingReadOnly\r\n * @restrict E\r\n * @description\r\n * Implementation of grading read only\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function gradingReadOnly() {\r\n function link(scope, element, attrs) {\r\n if(scope.settings){\r\n scope.grading.GradeType = scope.settings.GradeType;\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/TrainingReadOnly/grading-read-only.tpl.html',\r\n scope: {grading : \"=\", settings : \"=\"},\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('sectorHistory', sectorHistory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name sectorHistory\r\n * @restrict E\r\n * @description\r\n * Implementation of sector history\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function sectorHistory() {\r\n function link(scope, element, attrs) {\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/TrainingReadOnly/sector-history.tpl.html',\r\n scope: {history : \"=\"},\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n\r\n a3_cabin_reports.directive('syllabusProgressReadOnly', syllabusProgressReadOnly);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name syllabusReadOnly\r\n * @restrict E\r\n * @description\r\n * Initialize read only view of submitted syllabus\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n\r\n function syllabusProgressReadOnly() {\r\n function link(scope) {\r\n scope.showRemarks = {\r\n value: false\r\n };\r\n scope.oneAtATime = true;\r\n scope.filterItems = filterItems;\r\n scope.toggleItems = toggleItems;\r\n\r\n setSyllabus(scope.history);\r\n\r\n function setSyllabus(history) {\r\n var traineeSessionItems = [];\r\n scope.phase.Syllabus.SyllabusItems.forEach(function (item) {\r\n \r\n var syllabusItem = JSON.parse(JSON.stringify(item));\r\n syllabusItem.Tries = [];\r\n syllabusItem.Selected = false;\r\n\r\n var relatedSessionItem = history.SyllabusProgress.find(x => x.SyllabusItemId == syllabusItem.Id);\r\n \r\n if(relatedSessionItem){\r\n syllabusItem.hasRemarks = relatedSessionItem.Tries.some(x => x.Comments && x.Comments.length>0) ||\r\n relatedSessionItem.Tries.some(t=> t.TryGrading.Competences.some(x => x.Comments && x.Comments.length>0));\r\n syllabusItem.Selected = true;\r\n syllabusItem.Tries = relatedSessionItem.Tries;\r\n syllabusItem.Tries.forEach(function(attempt){\r\n attempt.Selected = true;\r\n });\r\n }\r\n\r\n setPanelStyle(syllabusItem); \r\n traineeSessionItems.push(syllabusItem);\r\n });\r\n\r\n history.ItemsGrouped = SyllabusGrouping(traineeSessionItems);\r\n }\r\n\r\n \r\n function setPanelStyle(item){\r\n var historyTriesCount = item.Tries.filter(x => x.isReadOnly).length;\r\n var newTriesCount = item.Tries.filter(x => !x.isReadOnly && x.Selected).length;\r\n item.TriesPerformedCount = historyTriesCount + newTriesCount;\r\n\r\n var completedItem = item.TriesPerformedCount >= item.MandatoryCount;\r\n\r\n if(item.MandatoryCount == 0){ //non-mandatory items are considered completed if performed at least once\r\n completedItem = item.TriesPerformedCount>=1;\r\n }\r\n\r\n if(completedItem){\r\n item.PanelClass = 'panel-green panel-border-left-green ';\r\n }\r\n else{\r\n item.PanelClass = 'panel-border-left-blue ';\r\n }\r\n }\r\n\r\n function SyllabusGrouping(items) {\r\n //Syllabus Items Group By 'GroupId'\r\n var syllabusGroups = [];\r\n items.forEach(function (item) {\r\n if (!syllabusGroups.some(x => x.Id == item.SelectedGroup.Id)) {\r\n if (!item.SelectedGroup) {\r\n item.SelectedGroup = {\r\n Id: 0,\r\n Title: 'General'\r\n };\r\n }\r\n\r\n var syllabusGroup = {\r\n Id: item.SelectedGroup.Id,\r\n Title: item.SelectedGroup.Title ? item.SelectedGroup.Title : 'General',\r\n Items: []\r\n };\r\n\r\n syllabusGroup.Items.push(item);\r\n syllabusGroups.push(syllabusGroup);\r\n }\r\n else {\r\n syllabusGroups.filter(x => x.Id == item.SelectedGroup.Id)[0].Items.push(item);\r\n }\r\n });\r\n\r\n return syllabusGroups;\r\n }\r\n\r\n function filterItems(){\r\n return function( item ) {\r\n var showItem = true;\r\n if(scope.showRemarks.value){\r\n showItem = item.hasRemarks;\r\n \r\n }\r\n else{\r\n scope.oneAtATime = true;\r\n }\r\n return showItem;\r\n };\r\n }\r\n\r\n function toggleItems(){\r\n scope.oneAtATime = !scope.showRemarks.value;\r\n \r\n scope.history.ItemsGrouped.forEach(function(syllabusGroup){\r\n syllabusGroup.Items.forEach(function(item){\r\n item.isOpen = scope.showRemarks.value;\r\n });\r\n });\r\n }\r\n }\r\n return {\r\n restrict: 'E',\r\n templateUrl: 'views/TrainingReadOnly/syllabus-progress-read-only.tpl.html',\r\n scope : { phase:\"=\", history:\"=\"},\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function () {\r\n\r\n a3_cabin_reports.directive('syllabusReadOnly', syllabusReadOnly);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name syllabusReadOnly\r\n * @restrict E\r\n * @description\r\n * Initialize read only view of submitted syllabus\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n\r\n function syllabusReadOnly() {\r\n function link(scope) {\r\n setSyllabus(scope.traineeSession);\r\n\r\n\r\n function setSyllabus(traineeSession) {\r\n\r\n var traineeSessionItems = [];\r\n scope.phase.Syllabus.SyllabusItems.forEach(function (item) {\r\n var syllabusItem = JSON.parse(JSON.stringify(item));\r\n syllabusItem.Tries = [];\r\n syllabusItem.Selected = false;\r\n\r\n var relatedSessionItem = null;\r\n if(scope.type == \"signature\"){\r\n relatedSessionItem = traineeSession.Items.find(x => x.Id == syllabusItem.Id);\r\n }\r\n else{\r\n relatedSessionItem = traineeSession.Items.find(x => x.SyllabusItemId == syllabusItem.Id);\r\n }\r\n\r\n if(relatedSessionItem){\r\n syllabusItem.Selected = true;\r\n syllabusItem.Tries = relatedSessionItem.Tries;\r\n }\r\n\r\n if(scope.type == \"signature\"){\r\n setPanelStyleByProgress(syllabusItem); \r\n }\r\n else{\r\n setPanelStyleBySelected(syllabusItem); \r\n }\r\n\r\n \r\n traineeSessionItems.push(syllabusItem);\r\n });\r\n\r\n traineeSession.ItemsGrouped = SyllabusGrouping(traineeSessionItems);\r\n\r\n traineeSession.ItemsGrouped.forEach(function(group){\r\n group.Items.forEach(function(item){\r\n //find first not ReadOnly try\r\n item.firstTry = item.Tries.find(x => !x.isReadOnly);\r\n });\r\n });\r\n }\r\n\r\n \r\n function setPanelStyleByProgress(item){\r\n var historyTriesCount = item.Tries.filter(x => x.isReadOnly).length;\r\n var newTriesCount = item.Tries.filter(x => !x.isReadOnly && x.Selected).length;\r\n item.TriesPerformedCount = historyTriesCount + newTriesCount;\r\n\r\n var completedItem = item.TriesPerformedCount >= item.MandatoryCount;\r\n\r\n if(item.MandatoryCount == 0){ //non-mandatory items are considered completed if performed at least once\r\n completedItem = item.TriesPerformedCount>=1;\r\n }\r\n\r\n var nonCompetentItem = false;\r\n if (item.IsGradable && item.Selected) {\r\n var gradingType = item.GradeType; //Numeric or Outcome or Competences\r\n var traineeSelectedTries = item.Tries.filter(x => x.Selected);\r\n\r\n traineeSelectedTries.forEach(function (selectedTry) {\r\n if(!invalidItem && gradingType == \"Outcome\" && selectedTry.TryGrading.Grade == \"Fail\"){\r\n nonCompetentItem = true;\r\n }\r\n \r\n });\r\n }\r\n\r\n if(completedItem && !nonCompetentItem){\r\n item.PanelClass = 'panel-green panel-border-left-green ';\r\n } else if(completedItem && nonCompetentItem){\r\n item.PanelClass = 'panel-border-left-pink';\r\n }\r\n else{\r\n item.PanelClass = 'panel-border-left-blue ';\r\n }\r\n }\r\n\r\n function setPanelStyleBySelected(item){\r\n var newTriesCount = item.Tries.filter(x => x.Selected).length;\r\n var selectedItem = newTriesCount>0;\r\n \r\n var nonCompetentItem = false;\r\n\r\n var completedItem = item.Tries.length >= item.MandatoryCount;\r\n if(item.MandatoryCount == 0){ //non-mandatory items are considered completed if performed at least once\r\n completedItem = item.TriesPerformedCount>=1;\r\n }\r\n \r\n if (item.IsGradable && item.Selected) {\r\n var outcomeType = item.GradeType == \"Outcome\";\r\n var traineeSelectedTries = item.Tries.filter(x => x.Selected);\r\n\r\n if(outcomeType){\r\n traineeSelectedTries.forEach(function (selectedTry) {\r\n if(outcomeType && selectedTry.TryGrading.Grade == \"Fail\"){\r\n nonCompetentItem = true;\r\n } \r\n });\r\n } \r\n }\r\n\r\n if(completedItem && selectedItem && !nonCompetentItem){\r\n item.PanelClass = 'panel-green panel-border-left-green ';\r\n } else if(completedItem && selectedItem && nonCompetentItem){\r\n item.PanelClass = 'panel-border-left-pink';\r\n }\r\n else{\r\n item.PanelClass = 'panel-border-left-blue ';\r\n }\r\n }\r\n\r\n\r\n function SyllabusGrouping(items) {\r\n //Syllabus Items Group By 'GroupId'\r\n var syllabusGroups = [];\r\n items.forEach(function (item) {\r\n if (!syllabusGroups.some(x => x.Id == item.SelectedGroup.Id)) {\r\n if (!item.SelectedGroup) {\r\n item.SelectedGroup = {\r\n Id: 0,\r\n Title: 'General'\r\n };\r\n }\r\n\r\n var syllabusGroup = {\r\n Id: item.SelectedGroup.Id,\r\n Title: item.SelectedGroup.Title ? item.SelectedGroup.Title : 'General',\r\n Items: []\r\n };\r\n\r\n syllabusGroup.Items.push(item);\r\n syllabusGroups.push(syllabusGroup);\r\n }\r\n else {\r\n syllabusGroups.filter(x => x.Id == item.SelectedGroup.Id)[0].Items.push(item);\r\n }\r\n });\r\n\r\n return syllabusGroups;\r\n }\r\n\r\n }\r\n return {\r\n restrict: 'E',\r\n templateUrl: 'views/TrainingReadOnly/syllabus-read-only.tpl.html',\r\n scope : { phase:\"=\", traineeSession:\"=\", type:\"=\"},\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('additionalTraining', additionalTraining);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name additionalTraining\r\n * @restrict E\r\n * @description\r\n * Implementation of additional Training\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function additionalTraining($uibModal) {\r\n function link(scope) {\r\n \r\n scope.filterTrainee = filterTrainee;\r\n scope.yesAdditional = yesAdditional;\r\n scope.noAdditional = noAdditional;\r\n scope.NeedsAdditionalTraining = false;\r\n scope.clearAdditionalNotes = clearAdditionalNotes;\r\n scope.remarksSelection = remarksSelection;\r\n\r\n scope.completeAdditional = completeAdditional;\r\n scope.continueAdditional = continueAdditional;\r\n scope.selectedTrainee.startAdditional = false;\r\n scope.initializeAdditional = initializeAdditional;\r\n scope.toggleAdditional = toggleAdditional;\r\n scope.selectedTrainee.continueAdditional = false;\r\n scope.openAdditionalModal = openAdditionalModal;\r\n \r\n function yesAdditional(trainee) {\r\n scope.selectedTrainee.NeedsAdditionalTraining = true;\r\n trainee.Session.NeedsAdditionalTraining = true;\r\n scope.CompleteAdditionalTraining = false;\r\n trainee.Session.CompleteAdditionalTraining = false;\r\n trainee.Session.UnderAdditionalTraining = false;\r\n scope.selectedTrainee.startAdditional = true;\r\n remarksSelection(trainee); \r\n }\r\n\r\n function noAdditional(trainee) {\r\n scope.selectedTrainee.NeedsAdditionalTraining = false;\r\n trainee.Session.NeedsAdditionalTraining = false;\r\n scope.CompleteAdditionalTraining = false;\r\n trainee.Session.CompleteAdditionalTraining = false;\r\n trainee.Session.UnderAdditionalTraining = false;\r\n trainee.Session.AdditionalTrainingStatus = 'None';\r\n clearAdditionalNotes(trainee);\r\n }\r\n\r\n function clearAdditionalNotes(trainee) {\r\n scope.selectedTrainee.Session.AdditionalTrainingRemarks = '';\r\n trainee.Session.AdditionalTrainingRemarks = '';\r\n }\r\n\r\n function completeAdditional(trainee) {\r\n scope.selectedTrainee.NeedsAdditionalTraining = false;\r\n trainee.Session.NeedsAdditionalTraining = false;\r\n scope.CompleteAdditionalTraining = true;\r\n trainee.Session.CompleteAdditionalTraining = true;\r\n trainee.Session.UnderAdditionalTraining = true;\r\n \r\n remarksSelection(trainee); \r\n }\r\n\r\n function continueAdditional(trainee) {\r\n scope.selectedTrainee.NeedsAdditionalTraining = true;\r\n trainee.Session.NeedsAdditionalTraining = true;\r\n scope.CompleteAdditionalTraining = false;\r\n trainee.Session.CompleteAdditionalTraining = false;\r\n trainee.Session.UnderAdditionalTraining = true;\r\n\r\n remarksSelection(trainee); \r\n }\r\n\r\n function filterTrainee(){\r\n return function(trainee) {\r\n var showTrainee = true;\r\n if(scope.selectedTrainee){ //individual grading view: filter selected\r\n showTrainee = scope.selectedTrainee.CrewId == trainee.CrewId\r\n }\r\n return showTrainee;\r\n };\r\n }\r\n\r\n function remarksSelection(trainee){\r\n trainee.Session.AdditionalTrainingRemarks = scope.selectedTrainee.Session.AdditionalTrainingRemarks; \r\n }\r\n\r\n function toggleAdditional(trainee){\r\n if(scope.selectedTrainee.continueAdditional){\r\n continueAdditional(trainee);\r\n }\r\n else{\r\n completeAdditional(trainee);\r\n }\r\n }\r\n\r\n function initializeAdditional(trainee){\r\n if(scope.selectedTrainee.startAdditional){\r\n yesAdditional(trainee);\r\n }\r\n else{\r\n noAdditional(trainee);\r\n }\r\n }\r\n\r\n function openAdditionalModal(userInput) {\r\n $uibModal.open({ \r\n templateUrl: 'views/Dialogs/dlgAdditionalTraining.html',\r\n controller: 'AdditionalTrainingModalCtrl',\r\n size: 'md',\r\n backdrop: 'static',\r\n keyboard: false,\r\n resolve: { \r\n retVal: function () {\r\n return userInput;\r\n }, \r\n startAdd: userInput \r\n }\r\n });\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: true,\r\n templateUrl: 'views/Training/additionalTraining.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('AdditionalTrainingModalCtrl', AdditionalTrainingModalCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name AdditionalTrainingModalCtrl\r\n * @description \r\n * Manages Additional Training Modal\r\n * @ngInject\r\n */\r\nfunction AdditionalTrainingModalCtrl($scope, $uibModalInstance, retVal) {\r\n\r\n $scope.ok = ok;\r\n\t\t$scope.cancel = cancel;\r\n \r\n if (retVal) {\r\n $scope.startAdd = true;\r\n\t\t} else {\r\n $scope.startAdd = false;\r\n\t\t}\r\n /**\r\n * Close modal after confirm\r\n * @memberof AdditionalTrainingModalCtrl\r\n */\r\n function ok() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n /**\r\n * Close Modal\r\n * @memberof AdditionalTrainingModalCtrl\r\n */\r\n function cancel() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('certificateExam', certificateExam);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name certificateExam\r\n * @restrict E\r\n * @description\r\n * Implementation of certificate exam grading\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function certificateExam(TrainingSessionFactory, FlightSessionFactory) {\r\n function link(scope, element, attrs) {\r\n if (scope.trainees) collapseAll();\r\n\r\n scope.validateTrainee = validateTrainee;\r\n scope.getRemainingCharacters = getRemainingCharacters;\r\n scope.collapseAll = collapseAll;\r\n scope.gradeUp = gradeUp;\r\n scope.gradeDown = gradeDown;\r\n\r\n var courseId = scope.dutyCourse.Id;\r\n\r\n var isGround = false;\r\n if(scope.groundDuty){\r\n isGround = true;\r\n var date = scope.groundDuty.DutyDateS;\r\n var dutyId = scope.groundDuty.Id;\r\n }\r\n else{\r\n var date = scope.crewRouteDuty.date;\r\n var dutyNo = scope.crewRouteDuty.DutyNo;\r\n var dutyDay = scope.crewRouteDuty.DutyDay;\r\n } \r\n\r\n var gradeBase = scope.selectedPhase.ReleaseGrading.CertificateGradeBase;\r\n\r\n scope.gradeBase = gradeBase;\r\n scope.gradeMin = 0;\r\n scope.gradeMax = 100;\r\n\r\n //Accordion setting\r\n scope.oneAtATime = true;\r\n scope.gradingStatus = 'All';\r\n\r\n\r\n //Initialize trainees \r\n scope.sessions = [];\r\n scope.trainees.filter(x => x.EligibilityStatus && !x.Session.Absent).forEach(function (trainee) {\r\n var session = trainee.Session.ReleaseGrading;\r\n session.Name = trainee.Name;\r\n session.AimsId = trainee.AimsId;\r\n session.isOpen = false;\r\n\r\n if(!session.CertificateOutcome) session.CertificateOutcome = \"Pass\";\r\n if(gradeBase && !session.Grade) session.Grade = gradeBase;\r\n if(!gradeBase) session.Grade = null;\r\n\r\n scope.sessions.push(session);\r\n });\r\n\r\n scope.sessions.forEach(function(traineeSession){\r\n validateGrading(traineeSession);\r\n });\r\n\r\n function validateGrading(trainee){\r\n // Invalid grading\r\n // 1. If none\r\n // 2. Over gradeMax\r\n // 3. Below gradeMin\r\n // 4. Non numeric\r\n trainee.isCertificateValid = gradeBase ? trainee.Grade != null && trainee.Grade != undefined : true;\r\n }\r\n\r\n function validateTrainee(trainee){\r\n if(gradeBase){\r\n validateGrading(trainee);\r\n if(trainee.isCertificateValid){\r\n calculateOutcome(trainee);\r\n }\r\n }\r\n \r\n if(isGround){\r\n TrainingSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyId, console.log, function (e) { console.log(e) })\r\n }\r\n else{\r\n FlightSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyNo, dutyDay, console.log, function (e) { console.log(e) })\r\n }\r\n }\r\n\r\n function gradeUp(trainee){\r\n if(trainee.isCertificateValid && trainee.Grade < scope.gradeMax){\r\n trainee.Grade++;\r\n }\r\n if(!trainee.isCertificateValid){\r\n trainee.Grade++;\r\n }\r\n validateTrainee(trainee);\r\n }\r\n\r\n function gradeDown(trainee){\r\n if(trainee.isExamValid && trainee.Grade > scope.gradeMin){\r\n trainee.Grade--;\r\n }\r\n if(!trainee.isExamValid){\r\n trainee.Grade--;\r\n }\r\n validateTrainee(trainee);\r\n }\r\n\r\n function calculateOutcome(trainee){\r\n if(trainee.Grade < gradeBase){\r\n trainee.CertificateOutcome = \"Fail\";\r\n }\r\n else{\r\n trainee.CertificateOutcome = \"Pass\";\r\n }\r\n }\r\n \r\n\r\n function getRemainingCharacters(text, max) {\r\n if (typeof (text) === \"undefined\" || text === null) return '';\r\n if (typeof (max) === \"undefined\" || max === null || max < 0 || !max) max = 4000;\r\n var length = text.length;\r\n\r\n return 'characters left: ' + (max - length);\r\n }\r\n\r\n function collapseAll() {\r\n scope.isAllOpen = !scope.isAllOpen;\r\n scope.trainees.forEach(function (trainee) {\r\n var session = trainee.Session.ReleaseGrading;\r\n session.isOpen = scope.isAllOpen;\r\n });\r\n }\r\n\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/Training/certificate-exam.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('CompetenceModalCtrl', CompetenceModalCtrl)\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CompetenceModalCtrl\r\n * @description \r\n * Show competence grading helper\r\n * @ngInject\r\n */\r\n\r\n function CompetenceModalCtrl($scope, $uibModalInstance, competence){\r\n $scope.close = close;\r\n $scope.competence = competence;\r\n\r\n /**\r\n * Close the modal\r\n * @memberof CompetenceModalCtrl\r\n */\r\n function close(){\r\n $uibModalInstance.close($scope.competence.Grading);\r\n }\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('courseFooter', courseFooter);\r\n\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name courseFooter\r\n * @restrict E\r\n * @description\r\n * Implementation of courseFooter (appears in course view)\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */\r\n function courseFooter($location, $routeParams) {\r\n function link(scope) {\r\n scope.gotoCalendar = gotoCalendar;\r\n scope.gotoGroundDuty = gotoGroundDuty;\r\n scope.gotoCrewRoute = gotoCrewRoute;\r\n scope.gotoFlight = gotoFlight;\r\n\r\n function gotoCalendar() {\r\n $location.path(\"/\");\r\n }\r\n\r\n function gotoGroundDuty() {\r\n $location.path('/groundDuty/' + Number($routeParams.dutyId));\r\n }\r\n\r\n function gotoCrewRoute() {\r\n var dutyNo = scope.crewRouteDuty.DutyNo;\r\n var dutyDay = scope.crewRouteDuty.DutyDay;\r\n $location.path('/crewRoute/' + dutyNo + '/' + dutyDay);\r\n }\r\n\r\n function gotoFlight(){\r\n var flightId = Number($routeParams.flightId)\r\n $location.path('/flightinfo/' + flightId);\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: true,\r\n templateUrl: \"views/Training/course-footer.tpl.html\",\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('course', course);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name course\r\n * @restrict E\r\n * @description\r\n * Implementation of training course\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function course(GroundDutyFactory, CourseFactory, TrainingSessionFactory, FlightSessionFactory, $timeout, $uibModal, $location, $routeParams, $window) {\r\n function link(scope) {\r\n var courseId = scope.dutyCourse.Id;\r\n\r\n var isGround = false;\r\n\r\n if(scope.groundDuty){\r\n isGround = true;\r\n var date = scope.groundDuty.DutyDateS;\r\n var dutyId = scope.groundDuty.Id;\r\n }\r\n else{\r\n var date = scope.crewRouteDuty.date;\r\n var dutyNo = scope.crewRouteDuty.DutyNo;\r\n var dutyDay = scope.crewRouteDuty.DutyDay;\r\n\r\n var trainingFlightIds = scope.crewRouteDuty.Courses.find(x => x.CourseId == courseId && new moment(x.Date).isSame(date)).TrainingFlightIds;\r\n \r\n if(scope.course.Media) scope.course.Media.radioModel = \"Flight\";\r\n }\r\n\r\n scope.isGround = isGround;\r\n \r\n scope.updateSession = updateSession;\r\n scope.availableCourseInfo = false;\r\n scope.oneTraineeAtATime = true;\r\n scope.allAbsent = false;\r\n scope.SubmitSession = SubmitSession;\r\n scope.close = close;\r\n scope.updateTraineeSignatures = updateTraineeSignatures;\r\n scope.checkReleaseAvailability = checkReleaseAvailability;\r\n scope.setReleaseStatus = setReleaseStatus;\r\n scope.reloadReleasePanel = reloadReleasePanel;\r\n scope.showReleasePanel = showReleasePanel;\r\n\r\n scope.filterSelectedSyllabus = filterSelectedSyllabus;\r\n scope.filterPresentTrainees = filterPresentTrainees;\r\n\r\n scope.selectedPhaseIndex = selectedPhaseIndex();\r\n\r\n scope.releaseTrainee = releaseTrainee;\r\n scope.showReleaseBtn = showReleaseBtn;\r\n scope.showGroupReleaseBtn = showGroupReleaseBtn;\r\n scope.releaseGroup = releaseGroup;\r\n scope.validateTraineeForm = validateTraineeForm;\r\n scope.openTraineeSignature = openTraineeSignature;\r\n scope.resetSignature = resetSignature;\r\n\r\n\r\n scope.getTraineeClass = getTraineeClass;\r\n scope.leftScroll = leftScroll;\r\n scope.rightScroll = rightScroll;\r\n scope.togglePanel = togglePanel;\r\n\r\n\r\n scope.isReleaseSelected = false;\r\n scope.toggleBtn = toggleBtn;\r\n \r\n scope.setAdditionalTrainingDetails = setAdditionalTrainingDetails;\r\n scope.hasLowDayGrading = hasLowDayGrading;\r\n scope.hasLowSyllabusGrading = hasLowSyllabusGrading;\r\n\r\n if(scope.selectedPhase.ModuleType == \"Training\" && scope.selectedPhase.EnableAdditionalTraining){\r\n scope.AvailableAdditionalTraining = true;\r\n }\r\n\r\n function setAdditionalTrainingDetails() {\r\n if(scope.isReleaseSelected){ \r\n if(scope.selectedTrainee.Session.AdditionalTrainingRemarks != undefined){\r\n scope.selectedTrainee.Session.AdditionalTrainingRemarks = '';\r\n }\r\n scope.selectedTrainee.Session.CompleteAdditionalTraining = true;\r\n scope.selectedTrainee.Session.NeedsAdditionalTraining = false;\r\n }\r\n \r\n }\r\n\r\n function toggleBtn() {\r\n scope.isReleaseSelected = !scope.isReleaseSelected;\r\n }\r\n\r\n function selectedPhaseIndex(){ \r\n var index = 0;\r\n scope.course.CrewCoursePhases.some(function(phase, i) {\r\n if (phase.PhaseId == scope.selectedPhase.PhaseId) {\r\n index = i;\r\n return true;\r\n }\r\n });\r\n return index;\r\n }\r\n\r\n function filterSelectedSyllabus(){\r\n return function( syllabus ) {\r\n var showTrainee = true;\r\n if(scope.traineeSyllabi && scope.traineeSyllabi.length > 1){\r\n showTrainee = syllabus.TraineeIds[0] == scope.selectedTrainee.CrewId;\r\n }\r\n return showTrainee;\r\n };\r\n }\r\n\r\n function filterPresentTrainees(){\r\n return function( trainee ) {\r\n return !trainee.Session.Absent;\r\n };\r\n }\r\n\r\n scope.reloadFooter = true;\r\n scope.reloadRelease = true;\r\n \r\n setTraineeSessions();\r\n updateSession();\r\n setReleaseStatus();\r\n\r\n function ResetTraineeSignatures(){\r\n scope.trainees.forEach(function(trainee){\r\n trainee.Session.Authorized = false;\r\n });\r\n }\r\n\r\n function setReleaseStatus(){\r\n scope.trainees.forEach(function(trainee){trainee.ShowReleaseWarning = false;});\r\n scope.course.AvailableRelease = checkReleaseAvailability();\r\n\r\n //Handle trainee signatures\r\n scope.requiresTraineeSignature = RequiresTraineeSignature();\r\n if(!scope.requiresTraineeSignature) ResetTraineeSignatures();\r\n scope.allSignaturesComplete = !scope.trainees.filter(x => !x.Session.Absent).some(x => !x.Session.Authorized);\r\n scope.someSignaturesComplete = scope.trainees.filter(x => !x.Session.Absent).some(x => x.Session.Authorized);\r\n\r\n //For flights : check minDays - minSectors\r\n if(!isGround && scope.course.AvailableRelease && (scope.selectedPhase.MinDays > 0 || scope.selectedPhase.MinSectors > 0)){\r\n scope.trainees.filter(x => x.AvailableRelease).forEach(function(trainee){\r\n var phaseInfo = trainee.Phases.find(x => x.PhaseId == scope.selectedPhase.PhaseId);\r\n var completedDays = 0;\r\n var completedSectors = 0;\r\n if(phaseInfo.Sessions){ //previous sessions\r\n completedDays = phaseInfo.Sessions.length;\r\n\r\n phaseInfo.Sessions.forEach(function(pastSession){\r\n if(pastSession.Sectors){\r\n completedSectors = completedSectors + pastSession.Sectors.length;\r\n }\r\n })\r\n }\r\n \r\n trainee.CompletedDays = completedDays + 1 ; //add current day\r\n trainee.CompletedSectors = completedSectors + trainingFlightIds.length; //add current sectors\r\n if(trainee.CompletedDays < scope.selectedPhase.MinDays || trainee.CompletedSectors < scope.selectedPhase.MinSectors){\r\n trainee.ShowReleaseWarning = true;\r\n }\r\n });\r\n }\r\n\r\n //For ground: check aircraft visits\r\n if(isGround && (scope.course.AvailableRelease || scope.selectedPhase.ModuleType==\"Check\") && scope.selectedPhase.AircraftTypes.length){\r\n var trainees = scope.trainees;\r\n if(scope.selectedPhase.ModuleType!=\"Check\") trainees.filter(x => x.AvailableRelease);\r\n trainees.forEach(function(trainee){\r\n var phaseInfo = trainee.Phases.find(x => x.PhaseId == scope.selectedPhase.PhaseId);\r\n var visitedAircrafts = [];\r\n \r\n if(phaseInfo.Sessions){ //previous sessions\r\n phaseInfo.Sessions.forEach(function(session){\r\n visitedAircrafts = visitedAircrafts.concat(session.AircraftTypesVisited)\r\n });\r\n }\r\n \r\n if(scope.course.Media){\r\n trainee.visitedAircrafts = visitedAircrafts.concat(scope.course.Media.inputAircrafts); //add current arvis\r\n }\r\n trainee.pendingAircrafts = [];\r\n trainee.pairPendingAircrafts = []; \r\n\r\n var pendingAircrafts = [];\r\n scope.selectedPhase.AircraftTypes.forEach(function(type){\r\n var array = type.split(',');\r\n\r\n //if arvi requirement is not met\r\n if (trainee.visitedAircrafts && !array.some(x => trainee.visitedAircrafts.includes(x))) {\r\n var pendingArviList = [];\r\n if (array.length > 1) \r\n {\r\n array.forEach(function(arvi){\r\n pendingArviList.push(arvi);\r\n });\r\n }\r\n else\r\n {\r\n pendingArviList.push(array[0]);\r\n }\r\n pendingAircrafts.push(pendingArviList);\r\n }\r\n });\r\n\r\n trainee.pendingAircrafts = pendingAircrafts;\r\n trainee.ShowReleaseWarning = trainee.pendingAircrafts.length>0;\r\n });\r\n }\r\n scope.showReleaseWarning = scope.trainees.some(x => x.ShowReleaseWarning);\r\n }\r\n\r\n function reloadReleasePanel(){\r\n setReleaseStatus();\r\n scope.reloadRelease = false;\r\n $timeout(function () {\r\n scope.reloadRelease = true;\r\n }, 100);\r\n\r\n }\r\n\r\n function updateSession() {\r\n scope.trainees.forEach(function(trainee) {trainee.Session.selected = false;});\r\n\r\n if(scope.selectedTraineeBadge && scope.trainees.find(x => x.CrewId == scope.selectedTraineeBadge.CrewId)){\r\n scope.trainees.find(x => x.CrewId == scope.selectedTraineeBadge.CrewId).Session.selected = true;\r\n scope.selectedTrainee = scope.trainees.find(x => x.Session.selected);\r\n }\r\n\r\n if(isGround){\r\n TrainingSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyId, console.log, function (e) { console.log(e) })\r\n }\r\n else{\r\n FlightSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyNo, dutyDay, console.log, function (e) { console.log(e) })\r\n }\r\n }\r\n\r\n function setTraineeSessions() {\r\n var phase = scope.selectedPhase;\r\n // Set Day Grading\r\n var dayCompetences = phase.DayGrading.Competences;\r\n dayCompetences.forEach(function (competence) { \r\n competence.MandatorySub = setSubCompetenceValues(competence.MandatorySubCompetences); \r\n competence.OptionalSub = setSubCompetenceValues(competence.OptionalSubCompetences); \r\n\r\n //Filter out from optional the ones common with mandatory\r\n competence.OptionalSub = competence.OptionalSub.filter(c => !competence.MandatorySub.includes(c));\r\n });\r\n\r\n\r\n var dayGradingSessions = scope.trainees.map(x => x.Session.DayGrading);\r\n dayGradingSessions.forEach(function (traineeSession) {\r\n traineeSession.Competences = setTraineeCompetences(dayCompetences, traineeSession);\r\n });\r\n\r\n // Set Release Grading\r\n var releaseCompetences = phase.ReleaseGrading.Competences;\r\n releaseCompetences.forEach(function (competence) { \r\n competence.MandatorySub = setSubCompetenceValues(competence.MandatorySubCompetences); \r\n competence.OptionalSub = setSubCompetenceValues(competence.OptionalSubCompetences);\r\n\r\n //Filter out from optional the ones common with mandatory\r\n competence.OptionalSub = competence.OptionalSub.filter(c => !competence.MandatorySub.includes(c));\r\n });\r\n var releaseGradingSessions = scope.trainees.map(x => x.Session.ReleaseGrading);\r\n releaseGradingSessions.forEach(function (traineeSession) {\r\n traineeSession.Competences = setTraineeCompetences(releaseCompetences, traineeSession);\r\n });\r\n\r\n // Set Syllabus\r\n if (scope.selectedPhase.Syllabus) setSyllabus();\r\n\r\n //Check if all are absent\r\n if(scope.trainees && scope.trainees.length && !scope.trainees.some(x => !x.Session.Absent)){\r\n scope.allAbsent = true;\r\n } \r\n }\r\n\r\n function setSyllabus() {\r\n var traineeSyllabi = [];\r\n\r\n if (!scope.selectedPhase.Syllabus.IsGradable && !scope.selectedPhase.InFlight) { //Non Gradable syllabus & Ground: All trainees share the same syllabus\r\n var traineeSyllabus = {\r\n TraineeIds: scope.trainees.filter(x => !x.Session.Absent).map(x => x.CrewId),\r\n Items: []\r\n };\r\n traineeSyllabi.push(traineeSyllabus);\r\n }\r\n else { //Gradable syllabus || flight: each trainee will have its own\r\n scope.trainees.filter(x => !x.Session.Absent).forEach(function (trainee) {\r\n var traineeSyllabus = {\r\n TraineeIds: [trainee.CrewId],\r\n Items: []\r\n };\r\n traineeSyllabi.push(traineeSyllabus);\r\n });\r\n }\r\n\r\n //Set syllabus item sub competences \r\n scope.selectedPhase.Syllabus.SyllabusItems.forEach(function (item) {\r\n item.Competences.forEach(function (competence) { \r\n competence.MandatorySub = setSubCompetenceValues(competence.MandatorySubCompetences); \r\n competence.OptionalSub = setSubCompetenceValues(competence.OptionalSubCompetences);\r\n\r\n //Filter out from optional the ones common with mandatory\r\n competence.OptionalSub = competence.OptionalSub.filter(c => !competence.MandatorySub.includes(c));\r\n });\r\n });\r\n\r\n scope.trainees.filter(x => !x.Session.Absent).forEach(function (trainee) { \r\n var traineeSessionItems = [];\r\n scope.selectedPhase.Syllabus.SyllabusItems.forEach(function (item) {\r\n var syllabusItem = JSON.parse(JSON.stringify(item));\r\n\r\n //Get any history tries\r\n var historyTries = [];\r\n if (syllabusItem.History && syllabusItem.History.length) {\r\n var itemsHistory = syllabusItem.History.filter(x => x.CrewId == trainee.CrewId);\r\n if (itemsHistory.length) {\r\n var allHistoryTries = [];\r\n itemsHistory.forEach(function(item){\r\n allHistoryTries = allHistoryTries.concat(item.Tries);\r\n });\r\n allHistoryTries.forEach(function (historyTry) {\r\n var performedTry = { \r\n ActionNo : historyTry.ActionNo,\r\n isReadOnly : true,\r\n Comments : historyTry.Comments,\r\n InstructorName : historyTry.InstructorName,\r\n SubmissionDate : historyTry.SubmissionDate,\r\n Grade : historyTry.TryGrading.Grade,\r\n AcTypes : historyTry.AcTypes,\r\n Sectors : historyTry.Sectors\r\n }; \r\n historyTries.push(performedTry);\r\n }) \r\n }\r\n }\r\n\r\n var relatedSessionItem = trainee.Session.Items.find(x => x.Id == syllabusItem.Id);\r\n\r\n //Pending tries\r\n var pendingTriesLeft = syllabusItem.MandatoryCount - historyTries.length;\r\n \r\n if(syllabusItem.MandatoryCount == 0 && historyTries.length == 0){ //for non-mandatory items: add 1 attempt if not already performed\r\n pendingTriesLeft = 1;\r\n }\r\n\r\n var pendingTries = [];\r\n for (var i = 0; i < pendingTriesLeft; i++) {\r\n pendingTries.push({\r\n Comments: null,\r\n ActionNo: (historyTries.length) + i + 1,\r\n isFirstTry: i == 0,\r\n TryGrading: { \r\n Grade: syllabusItem.DefaultGrade? syllabusItem.DefaultGrade : null, \r\n Competences: [], \r\n GradeType: syllabusItem.GradeType \r\n }\r\n });\r\n }\r\n\r\n //Add pending tries to history tries\r\n var tries = historyTries.concat(pendingTries);\r\n\r\n //Create syllabus item depending on existing values\r\n if (!relatedSessionItem) {\r\n tries.filter(x => !x.isReadOnly).forEach(function (attempt) {\r\n attempt.TryGrading.Competences = setTraineeCompetences(syllabusItem.Competences, attempt.TryGrading);\r\n });\r\n\r\n var newItem = {\r\n RepeatRequired: false,\r\n Selected: false,\r\n Tries: tries,\r\n PhaseId: scope.selectedPhase.PhaseId,\r\n Id: syllabusItem.Id\r\n };\r\n traineeSessionItems.push(newItem);\r\n mergeSyllabusItemWithSession(syllabusItem, newItem);\r\n }\r\n else {\r\n var sessionTries = [];\r\n tries.forEach(function (tryItem) {\r\n var relatedSessionTry = relatedSessionItem.Tries.find(x => x.ActionNo == tryItem.ActionNo);\r\n if (relatedSessionTry && !tryItem.isReadOnly) {\r\n sessionTries.push(deepCopy(relatedSessionTry));\r\n }\r\n else {\r\n sessionTries.push(deepCopy(tryItem));\r\n }\r\n });\r\n\r\n //Add any Extra tries\r\n if(syllabusItem.MandatoryCount>0){\r\n var extraTries = relatedSessionItem.Tries.filter(x => x.ActionNo > syllabusItem.MandatoryCount && !x.isReadOnly);\r\n sessionTries = sessionTries.concat(extraTries);\r\n }\r\n\r\n sessionTries.filter(x => !x.isReadOnly).forEach(function (attempt) {\r\n attempt.TryGrading.Competences = setTraineeCompetences(syllabusItem.Competences, attempt.TryGrading);\r\n });\r\n\r\n var existingItem = {\r\n RepeatRequired: relatedSessionItem.RepeatRequired,\r\n Selected: relatedSessionItem.Selected,\r\n Tries: sessionTries,\r\n PhaseId: scope.selectedPhase.PhaseId,\r\n Id: syllabusItem.Id\r\n };\r\n \r\n traineeSessionItems.push(existingItem);\r\n mergeSyllabusItemWithSession(syllabusItem, existingItem);\r\n }\r\n\r\n var traineeSyllabus = traineeSyllabi.find(x => x.TraineeIds.includes(trainee.CrewId));\r\n if (!traineeSyllabus.Items.some(x => x.Id == syllabusItem.Id)) { \r\n traineeSyllabus.Items.push(syllabusItem); \r\n }\r\n });\r\n\r\n trainee.Session.Items = traineeSessionItems;\r\n });\r\n\r\n\r\n\r\n traineeSyllabi.forEach(function(syllabus){\r\n SyllabusGrouping(syllabus);\r\n })\r\n scope.traineeSyllabi = traineeSyllabi;\r\n }\r\n\r\n function mergeSyllabusItemWithSession(syllabusItem, sessionItem) {\r\n syllabusItem.RepeatRequired = sessionItem.RepeatRequired;\r\n syllabusItem.Selected = sessionItem.Selected;\r\n syllabusItem.Tries = sessionItem.Tries;\r\n }\r\n\r\n function leftScroll() {\r\n document.querySelector('.horizontal-scroll').scrollLeft -= 500;\r\n }\r\n \r\n function rightScroll() {\r\n document.querySelector('.horizontal-scroll').scrollLeft += 500;\r\n }\r\n\r\n function deepCopy(originalObject) {\r\n return JSON.parse(JSON.stringify(originalObject));\r\n }\r\n\r\n function SyllabusGrouping(syllabus) {\r\n //Syllabus Items Group By 'GroupId'\r\n var syllabusGroups = [];\r\n syllabus.Items.forEach(function (item) {\r\n if (!syllabusGroups.some(x => x.Id == item.SelectedGroup.Id)) {\r\n if (!item.SelectedGroup) {\r\n item.SelectedGroup = {\r\n Id: 0,\r\n Title: 'General'\r\n };\r\n }\r\n\r\n var syllabusGroup = {\r\n Id: item.SelectedGroup.Id,\r\n Title: item.SelectedGroup.Title ? item.SelectedGroup.Title : 'General',\r\n Items: []\r\n };\r\n\r\n syllabusGroup.Items.push(item);\r\n syllabusGroups.push(syllabusGroup);\r\n }\r\n else {\r\n syllabusGroups.filter(x => x.Id == item.SelectedGroup.Id)[0].Items.push(item);\r\n }\r\n });\r\n\r\n syllabus.ItemsGrouped = syllabusGroups;\r\n }\r\n\r\n function setTraineeCompetences(competences, sessionItem) {\r\n var traineeCompetences = [];\r\n competences.forEach(function (competence) {\r\n var traineeCompetence = JSON.parse(JSON.stringify(competence));\r\n var existingCompetence = sessionItem.Competences.find(x => x.Id == traineeCompetence.Id);\r\n //Get saved values\r\n traineeCompetence.Grading = existingCompetence ? existingCompetence.Grading : null;\r\n traineeCompetence.Comments = existingCompetence ? existingCompetence.Comments : null;\r\n if (existingCompetence) {\r\n traineeCompetence.SubCompetences.filter(x => existingCompetence.SubCompetences.some(y => y.Id == x.Id)).forEach(function (commonSub) {\r\n commonSub.Selected = existingCompetence.SubCompetences.find(s => s.Id == commonSub.Id).Selected;\r\n });\r\n traineeCompetence.hasMandatory = traineeCompetence.MandatorySub.includes(Number(traineeCompetence.Grading));\r\n traineeCompetence.hasOptional = traineeCompetence.OptionalSub.includes(Number(traineeCompetence.Grading));\r\n }\r\n traineeCompetences.push(traineeCompetence);\r\n });\r\n return traineeCompetences;\r\n }\r\n\r\n \r\n function setSubCompetenceValues(current) {\r\n var updated = [];\r\n var first = parseInt(current[0], 10);\r\n var last = current[current.length - 1];\r\n\r\n if (first) {\r\n for (var i = first; i <= last; i++) {\r\n updated.push(i);\r\n }\r\n }\r\n return updated;\r\n }\r\n\r\n\r\n\r\n /***************************************************************** Submit ********************************************************************************/\r\n function SubmitSession() {\r\n setReleaseStatus();\r\n if (!isValidForm()) {\r\n scope.modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgSubmitValidation.html',\r\n scope: scope,\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'lg'\r\n });\r\n }\r\n else {\r\n\r\n if(isGround){\r\n //Last save before submission\r\n TrainingSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyId, function () {\r\n // Get all trainees found for this session (filter by course and date)\r\n TrainingSessionFactory.getSessionTrainees(courseId, date, dutyId, function (Trainees) {\r\n manageSubmission(Trainees);\r\n });\r\n });\r\n }\r\n else{\r\n //Last save before submission\r\n FlightSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyNo, dutyDay, function () {\r\n // Get all trainees found for this session (filter by course and date)\r\n FlightSessionFactory.getSessionTrainees(courseId, date, dutyNo, dutyDay, function (Trainees) {\r\n manageSubmission(Trainees);\r\n });\r\n });\r\n }\r\n }\r\n }\r\n\r\n\r\n function manageSubmission(Trainees){\r\n PrepareSessionForSubmission(Trainees);\r\n setReleaseStatus();\r\n \r\n var requiresInstructorSignature = RequiresInstructorSignature();\r\n\r\n var confirmationMsg = scope.selectedPhase.ReleaseGrading.ConfirmationMessage\r\n \r\n // submit now\r\n var releaseGrading = (scope.selectedPhase.ReleaseGrading.Comments || \r\n scope.selectedPhase.ReleaseGrading.GradeType == 'Numeric' || \r\n scope.selectedPhase.ReleaseGrading.GradeType == 'Outcome' ||\r\n scope.selectedPhase.ReleaseGrading.Competences.length) &&\r\n scope.selectedPhase.ReleaseGrading.GradeType != 'CertificateExam';\r\n\r\n //var isAdditionalTraining = false; \r\n var needsAdditionalTraining = false;\r\n if(scope.selectedTrainee != null){\r\n needsAdditionalTraining = scope.selectedTrainee.NeedsAdditionalTraining\r\n }\r\n\r\n scope.modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgSign.html',\r\n controller: 'SignatureModalCtrl',\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n courseId: function () { return courseId; },\r\n date: function () { return date; },\r\n dutyId: function () { return dutyId; },\r\n dutyNo: function () { return dutyNo; },\r\n dutyDay: function () { return dutyDay; },\r\n confirmationMsg: function () { return confirmationMsg; },\r\n requiresInstructorSignature: function () { return requiresInstructorSignature },\r\n trainees: function () { return scope.trainees },\r\n submitSession: function () { return SaveSession; },\r\n releaseGrading: function () { return releaseGrading;},\r\n isReleased: function () { return scope.course.ReleasedPhase;},\r\n needsAdditionalTraining: function () { return needsAdditionalTraining;} \r\n }\r\n });\r\n\r\n scope.modalInstance.result.then(function (result) {\r\n if(result.success){\r\n $location.path(\"/\");\r\n }\r\n });\r\n }\r\n\r\n function RequiresTraineeSignature(){\r\n // End of session signature\r\n var endOfSessionSignature = scope.selectedPhase.DayGrading.TraineeSignature;\r\n\r\n // End of module signature\r\n var endOfModuleSignature = scope.course.ReleasedPhase && scope.selectedPhase.ReleaseGrading.TraineeSignature;\r\n\r\n return endOfSessionSignature || endOfModuleSignature;\r\n }\r\n\r\n function RequiresInstructorSignature(){\r\n /* Instructor signature needed if\r\n 1. Syllabus attached needs signature\r\n 2. Completed syllabus items need signature\r\n 3. End of session needs signature\r\n 4. Module is released and end of module needs signature\r\n */\r\n\r\n // 1. Check if syllabus exists and needs signature\r\n var syllabusSignature = scope.selectedPhase.Syllabus && scope.selectedPhase.Syllabus.SignatureRequired;\r\n\r\n // 2. Filter selected syllabus items & check if they need signature\r\n var selectedItems = [];\r\n scope.trainees.forEach(function(trainee){\r\n var traineeSelectedItems = trainee.Session.Items.filter(x => x.Selected).map(x => x.Id);\r\n selectedItems = selectedItems.concat(traineeSelectedItems);\r\n })\r\n selectedItems = [...new Set(selectedItems)];\r\n\r\n var syllabusItemSignature = scope.selectedPhase.Syllabus && scope.selectedPhase.Syllabus.SyllabusItems.filter(x => selectedItems.includes(x.Id)).some(x => x.SignatureRequired);\r\n\r\n // 3. End of session signature\r\n var endOfSessionSignature = scope.selectedPhase.DayGrading.InstructorSignature;\r\n\r\n // 4. End of module signature\r\n var endOfModuleSignature = scope.course.AvailableRelease && scope.course.ReleasedPhase && scope.selectedPhase.ReleaseGrading.InstructorSignature;\r\n\r\n return syllabusSignature || syllabusItemSignature || endOfSessionSignature || endOfModuleSignature;\r\n }\r\n \r\n\r\n /**\r\n * Check if Release requirements are met\r\n * @param {object} group \r\n */\r\n function checkReleaseAvailability() {\r\n //Available Release if No pending mandatory items\r\n //Calculate item status for each trainee\r\n scope.trainees.filter(x => !x.Session.Absent).forEach(function(sessionTrainee){\r\n\r\n if(scope.selectedPhase.Syllabus){\r\n var syllabusItems = scope.selectedPhase.Syllabus.SyllabusItems;\r\n sessionTrainee.Session.Items.forEach(function(sessionItem){\r\n var performedTries = sessionItem.Tries.filter(x => x.isReadOnly || x.Selected).length; // history & current session\r\n var mandatoryCount = syllabusItems.find(x => x.Id == sessionItem.Id).MandatoryCount;\r\n\r\n sessionItem.Status = (mandatoryCount>0 && performedTries < mandatoryCount) ? \"Pending\" : \"Completed\";\r\n });\r\n \r\n sessionTrainee.AvailableRelease = !sessionTrainee.Session.Items.some(x => x.Status == \"Pending\");\r\n }\r\n else{\r\n sessionTrainee.AvailableRelease = true;\r\n }\r\n \r\n });\r\n \r\n if(scope.selectedPhase.ModuleType == \"Training\"){\r\n scope.trainees.filter(x => !x.Session.Absent && !x.AvailableRelease).forEach(function(trainee){\r\n trainee.Session.Released = false;\r\n });\r\n\r\n if(scope.trainees.filter(x => !x.Session.Absent).some(x => !x.AvailableRelease)){\r\n scope.trainees.filter(x => !x.Session.Absent).forEach(function(trainee){\r\n trainee.Session.Released = false;\r\n })\r\n }\r\n }\r\n\r\n scope.course.ReleasedPhase = scope.trainees.filter(x => !x.Absent).some(x => x.Session.Released);\r\n return !scope.trainees.filter(x => !x.Session.Absent).some(x => !x.AvailableRelease); \r\n \r\n }\r\n\r\n function SaveSession(password, withRelease) {\r\n scope.submittedSession.SignaturePassword = password;\r\n\r\n if(scope.submittedSession.TraineeSessions.filter(x => x.AdditionalTrainingStatus == 'UnderAdditionalTraining').length > 0){\r\n scope.submittedSession.TraineeSessions.filter(x => !x.Absent && scope.selectedTrainee.AdditionalTrainingStatus == 'UnderAdditionalTraining').forEach(function(trainee){\r\n if(!trainee.NeedsAdditionalTraining)\r\n {\r\n trainee.NeedsAdditionalTraining = false;\r\n trainee.UnderAdditionalTraining = true;\r\n trainee.CompleteAdditionalTraining = true;\r\n }\r\n });\r\n }\r\n if(scope.submittedSession.TraineeSessions.find(x => x.CompleteAdditionalTraining == true)) {\r\n scope.submittedSession.TraineeSessions.filter(x => !x.Absent && scope.selectedTrainee.AdditionalTrainingStatus == 'UnderAdditionalTraining').forEach(function(trainee){\r\n if(!trainee.NeedsAdditionalTraining)\r\n {\r\n trainee.NeedsAdditionalTraining = false;\r\n trainee.UnderAdditionalTraining = true;\r\n trainee.CompleteAdditionalTraining = true;\r\n }\r\n });\r\n }\r\n \r\n if(withRelease){\r\n scope.submittedSession.ReleasedPhase = true;\r\n scope.submittedSession.TraineeSessions.filter(x => !x.Absent).forEach(function(trainee){\r\n trainee.Released = true;\r\n });\r\n }\r\n\r\n if(isGround){\r\n return TrainingSessionFactory.submitSession(scope.submittedSession);\r\n }\r\n else{\r\n return FlightSessionFactory.submitSession(scope.submittedSession);\r\n }\r\n }\r\n\r\n function PrepareSessionForSubmission(Trainees) {\r\n // Filter Trainee Sessions\r\n var trainees = Trainees.filter(x => x.EligibilityStatus);\r\n trainees.forEach(function (trainee) {\r\n trainee.Session.Items = trainee.Session.Items.filter(x => x.Selected);\r\n \r\n // Empty absent trainee sessions\r\n if (trainee.Session.Absent) {\r\n trainee.Session.Items = [];\r\n trainee.Session.DayGrading.Comments = null;\r\n trainee.Session.DayGrading.Competences = [];\r\n trainee.Session.DayGrading.Grade = null;\r\n trainee.Session.ReleaseGrading.Comments = null;\r\n trainee.Session.ReleaseGrading.Competences = [];\r\n trainee.Session.ReleaseGrading.Grade = null;\r\n trainee.Session.NeedsAdditionalTraining = false;\r\n trainee.Session.AdditionalTrainingRemarks = null;\r\n }\r\n });\r\n\r\n var sessionSectors = [];\r\n if(!isGround){\r\n //Collect session sectors for flight\r\n trainingFlightIds.forEach(function(flightId){\r\n var sector = {\r\n FlightId : flightId,\r\n PM: null,\r\n PF: null,\r\n SessionSectorSeats : []\r\n };\r\n\r\n sessionSectors.push(sector);\r\n });\r\n\r\n }\r\n\r\n // Create Session\r\n scope.submittedSession = {\r\n SessionDate: date,\r\n CourseId: courseId,\r\n GroundDutyIds: isGround ? [dutyId] : [],\r\n Sectors: sessionSectors,\r\n AircraftVisits: scope.course.Media && scope.course.Media.radioModel == \"Aircraft\" ? scope.course.Media.inputAircrafts : [],\r\n SelectedMedia: scope.course.Media ? scope.course.Media.radioModel : \"\",\r\n SyntheticDeviceId: scope.course.Media && scope.course.Media.radioModel == \"Simulator\" ? scope.course.Media.selectedDevice.selection : null,\r\n ReleasedPhase: scope.course.ReleasedPhase,\r\n GradeType: scope.selectedPhase.DayGrading.GradeType,\r\n ReleaseGradeType: scope.selectedPhase.ReleaseGrading.GradeType,\r\n TraineeSessions: trainees.map(x => x.Session),\r\n SyllabusVersionId: scope.selectedPhase.Syllabus ? scope.selectedPhase.Syllabus.SyllabusVersionId : null,\r\n PhaseId: scope.selectedPhase.PhaseId,\r\n DowntimeDuration: scope.course.Media && scope.course.Media.radioModel == \"Simulator\" && scope.downtimeDuration.radioValue == 'true'? scope.downtimeDuration.minutes : null,\r\n };\r\n\r\n }\r\n\r\n\r\n function isValidForm() {\r\n /*Requirements before submitting a session\r\n 1. OnLine Mode\r\n 2. Date Allowed\r\n 3. Pending syllabus items\r\n 4. Pending syllabus items for different trainee\r\n 5. Media Validation\r\n 6. Day Grading\r\n 7. Release Grading\r\n 8. Certificate Exam Grading\r\n 9. Trainee Signature\r\n */\r\n\r\n var isValid = false;\r\n var info = {\r\n border: \"\",\r\n icon: \"\",\r\n msg: \"\",\r\n scrollToTop: false\r\n };\r\n\r\n if (!window.navigator.onLine) {\r\n info = {\r\n border: \"border-left-red\",\r\n icon: \"fa-warning text-red\",\r\n msg: \" Online mode is required in order to submit a training.

Check your connection and try again!

\",\r\n scrollToTop: false\r\n };\r\n }\r\n else if (!dateAllowed()) {\r\n info = {\r\n border: \"border-left-red\",\r\n icon: \"fa-calendar-times-o text-red\",\r\n msg: \"You can not submit a session earlier than its duty date!\",\r\n scrollToTop: false\r\n };\r\n }\r\n else if(scope.requiresTraineeSignature && !scope.allSignaturesComplete){\r\n\r\n if(scope.selectedTrainee && !scope.selectedTrainee.Session.Authorized){\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-pencil-square-o text-orange\",\r\n msg: \"\" + scope.selectedTrainee.Name + \" needs to sign the form!\",\r\n scrollToTop:false\r\n };\r\n }\r\n else{\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg: \"All trainees need to sign their forms!\",\r\n scrollToTop:true\r\n };\r\n }\r\n }\r\n else if (syllabusPending()) {\r\n var traineeDetailsMsg = \"\";\r\n if(scope.selectedTrainee && (scope.selectedPhase.Syllabus.IsGradable || scope.selectedPhase.InFlight)) {\r\n traineeDetailsMsg = \" for \" + scope.selectedTrainee.Name + \"\"\r\n }\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-calendar-times-o text-orange\",\r\n msg: \"Form cannot be submitted!

Please complete all mandatory syllabus items\" + traineeDetailsMsg +\"

\",\r\n scrollToTop:false\r\n };\r\n }\r\n else if(traineesPending()){\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-calendar-times-o text-orange\",\r\n msg: \"Form cannot be submitted!

Please complete all trainee forms.

\",\r\n scrollToTop:true\r\n };\r\n }\r\n else if (!isMediaValid()) {\r\n if (scope.hasNoAircraft) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-plane text-orange\",\r\n msg: \"You need to provide an aircraft type!\",\r\n scrollToTop:true\r\n };\r\n }\r\n else if (scope.hasNoDevice) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-plane text-orange\",\r\n msg: \"You need to select a synthetic device!\",\r\n scrollToTop:true\r\n };\r\n\r\n }\r\n }\r\n else if(!isSyllabusGradingValid()){\r\n var invalidTrainees = scope.trainees.filter(t => t.Session.SyllabusValidationErrors && t.Session.SyllabusValidationErrors.Items.length);\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg: \"Some of the selected syllabus items require a grading\",\r\n SyllabusErrors : invalidTrainees.map(t => t.Session.SyllabusValidationErrors),\r\n scrollToTop:false\r\n };\r\n }\r\n else if (!isGradingValid()) {\r\n if (!scope.gradingValidationInfo.isDayCompetencesValid || !scope.gradingValidationInfo.isReleaseCompetencesValid) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg: \"You need to grade all competences before submitting!\",\r\n scrollToTop:false\r\n };\r\n }\r\n else if (!scope.gradingValidationInfo.isDayGradingValid || !scope.gradingValidationInfo.isReleaseGradingValid) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg: \"You need to grade all trainees!\",\r\n scrollToTop:false\r\n };\r\n }\r\n else if (!scope.gradingValidationInfo.isCertificateGradingValid) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg: \"You need to grade all certificate exams!\",\r\n scrollToTop:false\r\n };\r\n }\r\n }\r\n else {\r\n isValid = true;\r\n }\r\n\r\n scope.info = info;\r\n return isValid;\r\n }\r\n\r\n \r\n function dateAllowed() {\r\n var dateAllowed = false;\r\n\r\n //Submission is allowed only on the day of the training and after\r\n var trainingDay = moment.utc(date).valueOf();\r\n var today = moment.utc().valueOf();\r\n\r\n if (today >= trainingDay) {\r\n dateAllowed = true;\r\n }\r\n\r\n return dateAllowed;\r\n }\r\n\r\n function syllabusPending(){\r\n var syllabus = scope.selectedPhase.Syllabus;\r\n var type = scope.selectedPhase.ModuleType;\r\n\r\n return syllabus && type == 'Check' && ( (scope.selectedTrainee && !scope.selectedTrainee.AvailableRelease) || ((!scope.selectedTrainee && scope.trainees.filter(x => !x.Session.Absent).some(x => !x.AvailableRelease))) );\r\n }\r\n\r\n function traineesPending(){\r\n var syllabus = scope.selectedPhase.Syllabus;\r\n var type = scope.selectedPhase.ModuleType;\r\n\r\n return syllabus && type == 'Check' && scope.selectedTrainee && scope.trainees.filter(x => !x.Session.Absent).some(x => !x.AvailableRelease);\r\n }\r\n\r\n function isSyllabusGradingValid(){\r\n var syllabus = scope.selectedPhase.Syllabus;\r\n if(syllabus && syllabus.IsGradable){\r\n \r\n var gradableSyllabusItems = syllabus.SyllabusItems.filter(x => x.IsGradable);\r\n var gradableSyllabusItemIds = gradableSyllabusItems.map(x => x.Id);\r\n\r\n //foreach trainee get selected tries that need grading\r\n scope.trainees.filter(x => !x.Session.Absent).forEach(function(trainee){\r\n var invalidItems = [];\r\n trainee.Session.Items.filter(x => x.Selected && gradableSyllabusItemIds.includes(x.Id)).forEach(function(selectedItem){\r\n var syllabusItem = gradableSyllabusItems.find(x => x.Id == selectedItem.Id);\r\n var gradingType = syllabusItem.GradeType; //Numeric or Outcome or Competences\r\n var traineeSelectedTries = selectedItem.Tries.filter(x => x.Selected);\r\n\r\n traineeSelectedTries.forEach(function(selectedTry){\r\n\r\n var invalidGrading = gradingType != \"Competences\" && !selectedTry.TryGrading.Grade;\r\n var invalidCompetences = gradingType == \"Competences\" && !selectedTry.TryGrading.isCompetenceValid;\r\n \r\n if(invalidGrading || invalidCompetences){\r\n invalidItems.push(syllabusItem.Title);\r\n }\r\n });\r\n });\r\n trainee.Session.SyllabusValidationErrors = {\r\n Name : trainee.Name,\r\n Items : invalidItems\r\n };\r\n }); \r\n }\r\n\r\n return !scope.trainees.some(t => t.Session.SyllabusValidationErrors && t.Session.SyllabusValidationErrors.Items.length);\r\n }\r\n\r\n function isGradingValid() {\r\n var isDayGradingValid = scope.selectedPhase.DayGrading.GradeType == \"NotSet\";\r\n var isReleaseGradingValid = scope.selectedPhase.ReleaseGrading.GradeType == \"NotSet\" || scope.selectedPhase.ReleaseGrading.GradeType == \"CertificateExam\" || !scope.course.AvailableRelease || !scope.course.ReleasedPhase;\r\n var isCertificateGradingValid = scope.selectedPhase.ReleaseGrading.GradeType != \"CertificateExam\" || !scope.course.ReleasedPhase;\r\n var isDayCompetencesValid = scope.selectedPhase.DayGrading.Competences.length == 0;\r\n var isReleaseCompetencesValid = scope.selectedPhase.ReleaseGrading.Competences.length == 0 || !scope.course.AvailableRelease || !scope.course.ReleasedPhase;\r\n\r\n if (!isDayGradingValid) isDayGradingValid = !scope.trainees.filter(x => !x.Session.Absent).some(x => !x.Session.DayGrading.isGradeValid);\r\n if (!isReleaseGradingValid) isReleaseGradingValid = !scope.trainees.filter(x => !x.Session.Absent && x.Session.Released).some(x => !x.Session.ReleaseGrading.isGradeValid);\r\n if (!isCertificateGradingValid) isCertificateGradingValid = !scope.trainees.filter(x => !x.Session.Absent && x.AvailableRelease).some(x => !x.Session.ReleaseGrading.isCertificateValid);\r\n\r\n\r\n if (!isDayCompetencesValid) isDayCompetencesValid = !scope.trainees.filter(x => !x.Session.Absent).some(x => !x.Session.DayGrading.isCompetenceValid);\r\n if (!isReleaseCompetencesValid) isReleaseCompetencesValid = !scope.trainees.filter(x => !x.Session.Absent && x.Session.Released).some(x => !x.Session.ReleaseGrading.isCompetenceValid);\r\n\r\n scope.gradingValidationInfo = {\r\n isDayGradingValid: isDayGradingValid,\r\n isReleaseGradingValid: isReleaseGradingValid,\r\n isDayCompetencesValid: isDayCompetencesValid,\r\n isReleaseCompetencesValid: isReleaseCompetencesValid,\r\n isCertificateGradingValid: isCertificateGradingValid\r\n };\r\n\r\n return isDayGradingValid && isReleaseGradingValid && isDayCompetencesValid && isReleaseCompetencesValid && isCertificateGradingValid;\r\n }\r\n\r\n function isTraineeGradingValid(trainee) {\r\n var isDayGradingValid = scope.selectedPhase.DayGrading.GradeType == \"NotSet\";\r\n var isReleaseGradingValid = scope.selectedPhase.ReleaseGrading.GradeType == \"NotSet\" || scope.selectedPhase.ReleaseGrading.GradeType == \"CertificateExam\" || !scope.course.AvailableRelease || !scope.course.ReleasedPhase;\r\n var isCertificateGradingValid = scope.selectedPhase.ReleaseGrading.GradeType != \"CertificateExam\" || !scope.course.ReleasedPhase;\r\n var isDayCompetencesValid = scope.selectedPhase.DayGrading.Competences.length == 0;\r\n var isReleaseCompetencesValid = scope.selectedPhase.ReleaseGrading.Competences.length == 0 || !scope.course.AvailableRelease || !scope.course.ReleasedPhase;\r\n\r\n if (!isDayGradingValid) isDayGradingValid = trainee.Session.DayGrading.isGradeValid;\r\n if (!isReleaseGradingValid) isReleaseGradingValid = !trainee.Session.Released || trainee.Session.ReleaseGrading.isGradeValid;\r\n if (!isCertificateGradingValid) isCertificateGradingValid = !trainee.AvailableRelease || trainee.Session.ReleaseGrading.isCertificateValid;\r\n\r\n\r\n if (!isDayCompetencesValid) isDayCompetencesValid = trainee.Session.DayGrading.isCompetenceValid;\r\n if (!isReleaseCompetencesValid) isReleaseCompetencesValid = !trainee.Session.Released || trainee.Session.ReleaseGrading.isCompetenceValid;\r\n\r\n trainee.Session.gradingValidationInfo = {\r\n isDayGradingValid: isDayGradingValid,\r\n isReleaseGradingValid: isReleaseGradingValid,\r\n isDayCompetencesValid: isDayCompetencesValid,\r\n isReleaseCompetencesValid: isReleaseCompetencesValid,\r\n isCertificateGradingValid: isCertificateGradingValid\r\n };\r\n\r\n return isDayGradingValid && isReleaseGradingValid && isDayCompetencesValid && isReleaseCompetencesValid && isCertificateGradingValid;\r\n }\r\n\r\n function hasLowDayGrading(trainee){\r\n scope.traineeHasLowGrading = false;\r\n var hasDayNumericGrading = scope.selectedPhase.DayGrading.GradeType == \"Numeric\";\r\n var hasDayOutcomeGrading = scope.selectedPhase.DayGrading.GradeType == \"Outcome\";\r\n var hasDayCompetences = scope.selectedPhase.DayGrading.Competences.length > 0;\r\n\r\n if(trainee != null) {\r\n if(hasDayNumericGrading && (trainee.Session.DayGrading.Grade == 1 || trainee.Session.DayGrading.Grade == 2)) {\r\n scope.traineeHasLowGrading = true;\r\n }\r\n if(hasDayOutcomeGrading && (trainee.Session.DayGrading.Grade == \"Fail\" || trainee.Session.DayGrading.Grade == \"PasswithTrainingRecommendation\")) {\r\n scope.traineeHasLowGrading = true;\r\n }\r\n if(hasDayCompetences) {\r\n trainee.Session.DayGrading.Competences.forEach(function (competence) {\r\n if(competence.hasMandatory) \r\n scope.traineeHasLowGrading = true;\r\n }) \r\n }\r\n }\r\n \r\n\r\n return scope.traineeHasLowGrading;\r\n }\r\n\r\n function hasLowSyllabusGrading(trainee){\r\n scope.traineeHasLowSyllabusGrading = false;\r\n\r\n var syllabus = scope.selectedPhase.Syllabus;\r\n if(trainee != null){\r\n if(syllabus && syllabus.IsGradable){\r\n \r\n var gradableSyllabusItems = syllabus.SyllabusItems.filter(x => x.IsGradable);\r\n var gradableSyllabusItemIds = gradableSyllabusItems.map(x => x.Id);\r\n \r\n //get selected tries that has low grading\r\n trainee.Session.Items.filter(x => x.Selected && gradableSyllabusItemIds.includes(x.Id)).forEach(function(selectedItem){\r\n var traineeSelectedTries = selectedItem.Tries.filter(x => x.Selected);\r\n \r\n traineeSelectedTries.forEach(function(selectedTry){\r\n if(selectedTry.TryGrading.Grade == 1 || selectedTry.TryGrading.Grade == 2 || selectedTry.TryGrading.Grade == 'Fail')\r\n scope.traineeHasLowSyllabusGrading = true;\r\n \r\n if(selectedTry.TryGrading.GradeType == 'Competences'){\r\n selectedTry.TryGrading.Competences.forEach(function (competence) {\r\n if(competence.hasMandatory) \r\n scope.traineeHasLowSyllabusGrading = true;\r\n })\r\n }\r\n });\r\n \r\n });\r\n \r\n }\r\n }\r\n \r\n return scope.traineeHasLowSyllabusGrading;\r\n }\r\n\r\n function isMediaValid() {\r\n scope.hasNoAircraft = scope.course.Media && scope.course.Media.radioModel == \"Aircraft\" && !scope.course.Media.inputAircrafts.length;\r\n scope.hasNoDevice = scope.course.Media && scope.course.Media.radioModel == \"Simulator\" && !scope.course.Media.selectedDevice.selection;\r\n return !scope.hasNoAircraft && !scope.hasNoDevice;\r\n }\r\n\r\n /**\r\n * Triggered after a trainee has successfully signed\r\n */\r\n function updateTraineeSignatures(){\r\n updateSession();\r\n scope.allSignaturesComplete = !scope.trainees.filter(x => !x.Session.Absent).some(x => !x.Session.Authorized);\r\n scope.someSignaturesComplete = scope.trainees.filter(x => !x.Session.Absent).some(x => x.Session.Authorized);\r\n }\r\n\r\n function close() {\r\n scope.modalInstance.close();\r\n\r\n if(scope.info && scope.info.scrollToTop){\r\n $window.scrollTo(0, 0);\r\n }\r\n }\r\n\r\n function showReleasePanel(syllabus){\r\n var retVal = false;\r\n var phase = scope.selectedPhase;\r\n \r\n var availableCourse = scope.availableCourse && scope.trainees.length;\r\n var isCheck = phase.ModuleType=='Check';\r\n var releaseGrading = (phase.ReleaseGrading.Comments || \r\n phase.ReleaseGrading.GradeType == 'Numeric' || \r\n phase.ReleaseGrading.GradeType == 'Outcome' ||\r\n phase.ReleaseGrading.Competences.length) &&\r\n phase.ReleaseGrading.GradeType != 'CertificateExam';\r\n\r\n if(isCheck){\r\n retVal = availableCourse && releaseGrading;\r\n }\r\n else if(scope.traineeSyllabi.length > 1){\r\n var crewId = syllabus.TraineeIds[0];\r\n var trainee = scope.trainees.find(x => x.CrewId == crewId);\r\n retVal = scope.reloadRelease && trainee.AvailableRelease && trainee.Session.Released && availableCourse && releaseGrading;\r\n }\r\n else{\r\n retVal = scope.reloadRelease && scope.course.AvailableRelease && scope.course.ReleasedPhase && availableCourse && releaseGrading;\r\n }\r\n return retVal;\r\n }\r\n\r\n function releaseTrainee(syllabus){\r\n\r\n var crewIds = syllabus.TraineeIds;\r\n var trainees = scope.trainees.filter(x => crewIds.includes(x.CrewId));\r\n\r\n trainees.forEach(function(trainee){\r\n trainee.Session.Released = !trainee.Session.Released;\r\n });\r\n\r\n scope.course.ReleasedPhase = scope.trainees.filter(x => !x.Absent).some(x => x.Session.Released);\r\n }\r\n\r\n function releaseGroup(){\r\n scope.trainees.filter(x => !x.Session.Absent).forEach(function(trainee){\r\n trainee.Session.Released = !trainee.Session.Released;\r\n });\r\n\r\n scope.course.ReleasedPhase = scope.trainees.filter(x => !x.Absent).some(x => x.Session.Released);\r\n\r\n setReleaseStatus();\r\n }\r\n\r\n function showReleaseBtn(syllabus){\r\n var retVal = false;\r\n\r\n var availableCourse = scope.availableCourse && scope.trainees.length;\r\n var isCheck = scope.selectedPhase.ModuleType=='Check';\r\n \r\n\r\n if(isCheck){\r\n retVal = false;\r\n }\r\n else if(scope.traineeSyllabi.length > 1){\r\n var crewId = syllabus.TraineeIds[0];\r\n var trainee = scope.trainees.find(x => x.CrewId == crewId);\r\n retVal = scope.reloadRelease && availableCourse && trainee.AvailableRelease && trainee.AdditionalTrainingStatus == 'UnderAdditionalTraining';\r\n }\r\n else{\r\n retVal = scope.reloadRelease && availableCourse && scope.course.AvailableRelease;\r\n }\r\n\r\n return retVal;\r\n }\r\n\r\n function showGroupReleaseBtn(){\r\n var retVal = false;\r\n\r\n var availableCourse = scope.availableCourse && scope.trainees.length>0;\r\n var isCheck = scope.selectedPhase.ModuleType=='Check';\r\n var releaseGrading = (scope.selectedPhase.ReleaseGrading.Comments || \r\n scope.selectedPhase.ReleaseGrading.GradeType == 'Numeric' || \r\n scope.selectedPhase.ReleaseGrading.GradeType == 'Outcome' ||\r\n scope.selectedPhase.ReleaseGrading.Competences.length) &&\r\n scope.selectedPhase.ReleaseGrading.GradeType != 'CertificateExam';\r\n \r\n\r\n if(isCheck){\r\n retVal = false;\r\n }\r\n else{\r\n retVal = scope.reloadRelease && availableCourse && releaseGrading && !scope.trainees.filter(x => !x.Session.Absent).some(x => !x.AvailableRelease && x.AdditionalTrainingStatus != 'UnderAdditionalTraining');\r\n }\r\n\r\n return retVal;\r\n }\r\n\r\n function getTraineeClass(crewId){\r\n\r\n isSyllabusGradingValid();\r\n\r\n var textClass=\"\";\r\n\r\n var trainee = scope.trainees.find(x => x.CrewId == crewId);\r\n var syllabus = scope.selectedPhase.Syllabus;\r\n var type = scope.selectedPhase.ModuleType;\r\n \r\n var allSyllabusCompleted = trainee.AvailableRelease;\r\n\r\n //Draft status\r\n var selectedItems = trainee.Session.Items.some(i => i.Tries.filter(t => !t.isReadOnly).some(t => t.Selected));\r\n\r\n //Validate syllabus\r\n var validSyllabusGrading = !trainee.Session.SyllabusValidationErrors || !trainee.Session.SyllabusValidationErrors.Items.length;\r\n \r\n //Validate Day grading\r\n var isDayGradingValid = scope.selectedPhase.DayGrading.GradeType == \"NotSet\";\r\n var isDayCompetencesValid = scope.selectedPhase.DayGrading.Competences.length == 0;\r\n if (!isDayGradingValid) isDayGradingValid = trainee.Session.DayGrading.isGradeValid;\r\n if (!isDayCompetencesValid) isDayCompetencesValid = trainee.Session.DayGrading.isCompetenceValid;\r\n\r\n\r\n //Validate Release grading\r\n var isReleaseGradingValid = scope.selectedPhase.ReleaseGrading.GradeType == \"NotSet\" || scope.selectedPhase.ReleaseGrading.GradeType == \"CertificateExam\" \r\n || (scope.selectedPhase.ModuleType == \"Training\" && (!trainee.AvailableRelease || !trainee.Session.Released));\r\n\r\n var isReleaseCompetencesValid = scope.selectedPhase.ReleaseGrading.Competences.length == 0 \r\n || (scope.selectedPhase.ModuleType == \"Training\" && (!trainee.AvailableRelease || !trainee.Session.Released));\r\n if (!isReleaseGradingValid) isReleaseGradingValid = !trainee.Session.Released || trainee.Session.ReleaseGrading.isGradeValid;\r\n if (!isReleaseCompetencesValid) isReleaseCompetencesValid = !trainee.Session.Released || trainee.Session.ReleaseGrading.isCompetenceValid;\r\n\r\n\r\n\r\n if(selectedItems){\r\n textClass = \"bg-amber text-white\";\r\n if(validSyllabusGrading && isDayGradingValid && isDayCompetencesValid && isReleaseGradingValid && isReleaseCompetencesValid\r\n && (type =='Training' || allSyllabusCompleted)){\r\n textClass = \"bg-green text-white\";\r\n }\r\n }\r\n \r\n return textClass;\r\n }\r\n\r\n function togglePanel(panelId) {\r\n $('#' + panelId).toggle();\r\n }\r\n\r\n\r\n /**\r\n * Toggle signature panel while trainee hasn't signed yet\r\n * @param {object} trainee \r\n */\r\n function openTraineeSignature(trainee){\r\n //Enter signature mode : trainee form becomes read-only\r\n if(!trainee.Session.Authorized){\r\n setReleaseStatus();\r\n //Trainee can sign only if his form is valid\r\n if (!validateTraineeForm(trainee)) {\r\n scope.modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgSubmitValidation.html',\r\n scope: scope,\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'lg'\r\n });\r\n }\r\n else{\r\n scope.modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgTraineeSignature.html',\r\n controller: 'TraineeSignatureModalCtrl',\r\n scope: scope,\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n trainee: function () { return trainee; },\r\n signatureSuccess: function () { return updateTraineeSignatures; }\r\n }\r\n });\r\n }\r\n }\r\n\r\n scope.someSignaturesComplete = scope.trainees.filter(x => !x.Session.Absent).some(x => x.Session.Authorized);\r\n }\r\n\r\n function validateTraineeForm(trainee) {\r\n var trainee = scope.selectedTrainee;\r\n\r\n var isValid = false;\r\n var info = {\r\n border: \"\",\r\n icon: \"\",\r\n msg: \"\",\r\n scrollToTop: false\r\n };\r\n\r\n if (!window.navigator.onLine) {\r\n info = {\r\n border: \"border-left-red\",\r\n icon: \"fa-warning text-red\",\r\n msg: \" Online mode is required in order to sign.

Check your connection and try again!

\",\r\n scrollToTop: false\r\n };\r\n }\r\n else if (syllabusPending()) {\r\n var traineeDetailsMsg = \"\";\r\n if(trainee && (scope.selectedPhase.Syllabus.IsGradable || scope.selectedPhase.InFlight)) {\r\n traineeDetailsMsg = \" for \" + trainee.Name + \"\"\r\n }\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-calendar-times-o text-orange\",\r\n msg: \"Form cannot be submitted!

Please complete all mandatory syllabus items\" + traineeDetailsMsg +\"

\",\r\n scrollToTop:false\r\n };\r\n }\r\n else if(!isSyllabusGradingValid() && trainee.Session.SyllabusValidationErrors && trainee.Session.SyllabusValidationErrors.Items.length){\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg: \"Some of the selected syllabus items require a grading\",\r\n SyllabusErrors : trainee.Session.SyllabusValidationErrors,\r\n scrollToTop:false\r\n };\r\n }\r\n else if (!isTraineeGradingValid(trainee)) {\r\n if (!trainee.Session.gradingValidationInfo.isDayCompetencesValid || !trainee.Session.gradingValidationInfo.isReleaseCompetencesValid) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg: \"You need to grade all competences!\",\r\n scrollToTop:false\r\n };\r\n }\r\n else if (!trainee.Session.isDayGradingValid || !trainee.Session.isReleaseGradingValid) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg: \"You need to select an overall grade !\",\r\n scrollToTop:false\r\n };\r\n }\r\n else if (!trainee.Session.isCertificateGradingValid) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg: \"You need to grade all certificate exams!\",\r\n scrollToTop:false\r\n };\r\n }\r\n }\r\n else {\r\n isValid = true;\r\n }\r\n\r\n scope.info = info;\r\n \r\n \r\n return isValid;\r\n }\r\n\r\n function resetSignature(trainee){\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgResetSignature.html',\r\n controller: 'TraineeSignatureModalCtrl',\r\n scope: scope,\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n trainee: function () { return trainee; },\r\n signatureSuccess: function () { return updateTraineeSignatures; }\r\n }\r\n });\r\n\r\n modalInstance.result.then(function (confirm) {\r\n if(confirm){\r\n trainee.Session.Authorized = false;\r\n scope.trainees.find(x => x.CrewId == trainee.CrewId).Session.Authorized = false;\r\n updateTraineeSignatures();\r\n }\r\n \r\n });\r\n\r\n \r\n }\r\n }\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/Training/course.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('CourseFactory', CourseFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CourseFactory\r\n * @description \r\n * Add, Update, Delete and Get Training Courses.\r\n * @ngInject\r\n */\r\n function CourseFactory(IndexedDBService, GroundDutyFactory, $http, apiUrl) {\r\n\r\n /**\r\n * Initialize Course\r\n * @memberof CourseFactory\r\n */\r\n function Course() {\r\n this.Id = null;\r\n }\r\n\r\n var objType = 'Courses';\r\n var objCallback = Course;\r\n\r\n var service = {\r\n setCoursesFromServer: setCoursesFromServer,\r\n setCoursesToStorage: setCoursesToStorage, //save all courses\r\n getCourseFromStorage: getCourseFromStorage,\r\n addCourseToStorage: addCourseToStorage, //update course\r\n saveOneCourseToStorage: saveOneCourseToStorage, //save course\r\n getCoursesFromStorage: getCoursesFromStorage, //get all\r\n updateCourseInfo: updateCourseInfo,\r\n updateFlightCourseInfo: updateFlightCourseInfo,\r\n getCoursesFromStorageByIds: getCoursesFromStorageByIds,\r\n setCourseOutdated: setCourseOutdated,\r\n upsertCourse : upsertCourse\r\n };\r\n\r\n /**\r\n * Get Course By Id\r\n * @memberof CourseFactory\r\n * @param {function} callback \r\n */\r\n function getCourseFromStorage(courseId, callback, errorCallback) {\r\n IndexedDBService.getById(objType, courseId).then(function(result) {\r\n callback(result);\r\n }).catch(errorCallback);\r\n };\r\n\r\n /**\r\n * Get Courses\r\n * @memberof CourseFactory\r\n * @param {function} callback \r\n */\r\n function getCoursesFromStorage(callback, errorCallback) {\r\n IndexedDBService.getAll(objType).then(function(results) {\r\n callback(results);\r\n }).catch(errorCallback);\r\n };\r\n\r\n\r\n /**\r\n * Get Course By Ids\r\n * @memberof CourseFactory\r\n * @param {function} callback \r\n */\r\n function getCoursesFromStorageByIds(courseIds, callback, errorCallback) {\r\n IndexedDBService.getAll(objType).then(function(results) {\r\n var selectedResults = [];\r\n results.forEach(function(result) {\r\n if (courseIds.includes(result.Id) && selectedResults.filter(x => x.Id == result.Id).length == 0) {\r\n selectedResults.push(result);\r\n }\r\n })\r\n callback(selectedResults);\r\n }).catch(errorCallback);\r\n };\r\n\r\n \r\n\r\n function updateCourseInfo(courseId, dutyId, callback, errorOnSaveCallback, errorOnNetwork) {\r\n var traingingApiURL = apiUrl + '/Training?courseId=' + courseId + '&dutyId=' + dutyId;\r\n $http.get(traingingApiURL, { 'Content-Type': 'application/json' })\r\n .then(function(data) {\r\n var course = data.data;\r\n course.FetchedTime = moment.utc().toJSON();\r\n var duty = GroundDutyFactory.getGroundDutyFromStorage(dutyId);\r\n course.FetchedDutyCodes = duty.RelatedGroundDuties.filter(x => !x.IsInstructor).map(x => String(x.GroundDutyNo));\r\n course.LastFetchedDutyId = dutyId;\r\n //Upsert course in IndexDB \r\n upsertCourse(course, function(course){\r\n callback(course);\r\n }, errorOnSaveCallback);\r\n })\r\n .catch(errorOnNetwork)\r\n }\r\n\r\n function updateFlightCourseInfo(crewRouteCourse, date, dutyNo, dutyDay, callback, errorOnSaveCallback, errorOnNetwork) {\r\n var traingingApiURL = apiUrl + '/Training/GetCrewRouteTraining';\r\n $http.post(traingingApiURL, crewRouteCourse, { 'Content-Type': 'application/json' })\r\n .then(function(data) {\r\n var course = data.data;\r\n\r\n course.FetchedTime = moment.utc().toJSON();\r\n\r\n course.FetchedCrewRoute = {\r\n date: date,\r\n dutyNo: dutyNo,\r\n dutyDay: dutyDay\r\n };\r\n\r\n //Upsert course in IndexDB \r\n upsertCourse(course, function(course){\r\n callback(course);\r\n }, errorOnSaveCallback);\r\n })\r\n .catch(errorOnNetwork)\r\n }\r\n\r\n function upsertCourse(course, callback, errorOnSaveCallback){\r\n getCourseFromStorage(course.Id, function(localCourse) {\r\n if (localCourse) {\r\n saveOneCourseToStorage(course);\r\n } else {\r\n addCourseToStorage(course);\r\n }\r\n callback(course);\r\n }, errorOnSaveCallback);\r\n }\r\n\r\n function setCourseOutdated(courseId, callback, errorCallback) {\r\n getCourseFromStorage(courseId, function(localCourse) {\r\n if (localCourse) {\r\n localCourse.NeedsRefresh = true;\r\n saveOneCourseToStorage(localCourse);\r\n }\r\n\r\n if (callback) {\r\n callback();\r\n }\r\n }, errorCallback)\r\n }\r\n\r\n\r\n\r\n /**\r\n * Set Courses from server API \r\n * @memberof CourseFactory\r\n * @param {array} courses Courses Object\r\n * @param {array} courseIdsToSend Current courses of the storage\r\n * @param {string} lastSyncDate Last Sync Date \r\n */\r\n function setCoursesFromServer(courses, callback, errorCallback) {\r\n\r\n getCoursesFromStorage(function(localCourses) {\r\n // No courses found - Save All Incoming\r\n if (!localCourses || localCourses.length == 0) {\r\n setCoursesToStorage(courses);\r\n } else {\r\n for (var j = 0; j < courses.length; j++) {\r\n var IsCourseIncluded = false;\r\n\r\n for (var h = 0; h < localCourses.length; h++) {\r\n if (courses[j].Id == localCourses[h].Id) {\r\n IsCourseIncluded = true;\r\n break;\r\n }\r\n }\r\n\r\n //Update existing course\r\n if (IsCourseIncluded) {\r\n localCourses[h].Title = courses[j].Title; //Update title from sync\r\n saveOneCourseToStorage(localCourses[h]);\r\n }\r\n //Add a new Course\r\n else {\r\n addCourseToStorage(courses[j]);\r\n }\r\n }\r\n\r\n localCourses.filter(x => !courses.some(z => z.Id == x.Id)).forEach(function(course) {\r\n IndexedDBService.remove(objType, course.Id)\r\n })\r\n }\r\n })\r\n\r\n }\r\n\r\n /**\r\n * Set Courses\r\n * @memberof CourseFactory\r\n * @param {array} Courses A list of courses to set to indexedDB\r\n */\r\n function setCoursesToStorage(Courses, callback, errorCallback) {\r\n IndexedDBService.addAll(objType, Courses).then(callback).catch(errorCallback);\r\n };\r\n\r\n /**\r\n * Add Course to Storage\r\n * @memberof CourseFactory\r\n * @param {object} Course\r\n */\r\n function addCourseToStorage(Course, callback, errorCallback) {\r\n IndexedDBService.add(objType, Course).then(callback).catch(errorCallback);\r\n };\r\n\r\n /**\r\n * Update Course to Storage\r\n * @memberof CourseFactory\r\n * @param {object} Course\r\n */\r\n function saveOneCourseToStorage(Course, callback, errorCallback) {\r\n IndexedDBService.put(objType, Course).then(callback).catch(errorCallback);\r\n };\r\n\r\n return service;\r\n }\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('FlightSessionFactory', FlightSessionFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FlightSessionFactory\r\n * @description \r\n * Add, Update, Delete and Flight Sessions.\r\n * @ngInject\r\n */\r\n function FlightSessionFactory(IndexedDBService, CrewRouteFactory, FlightFactory, CourseFactory, $http, apiUrl, $filter) {\r\n\r\n /**\r\n * Initialize Session\r\n * @memberof FlightSessionFactory\r\n */\r\n function Session() {\r\n this.Id = null;\r\n }\r\n\r\n var objType = 'FlightSessions';\r\n var objCallback = Session;\r\n\r\n var service = {\r\n getAll: getAll,\r\n getSession: getSession,\r\n setSession: setSession,\r\n updateSession: updateSession,\r\n getSessionTrainees: getSessionTrainees,\r\n submitSession: submitSession,\r\n remove: remove,\r\n getCrewRouteFlightTrainees : getCrewRouteFlightTrainees,\r\n applyTraineeInfoToSession : applyTraineeInfoToSession\r\n };\r\n\r\n /**\r\n * Get all flight training sessions\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\r\n function getAll(callback) {\r\n IndexedDBService.getAll(objType).then(function(results){\r\n callback(results);\r\n });\r\n };\r\n\r\n\r\n /**\r\n * Get session By day and courseId\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\r\n function getSession(courseId, day, dutyNo, dutyDay, trainingFlightIds, afterRefresh, callback, errorCallback) {\r\n IndexedDBService.getById(objType, [day, courseId, dutyNo, dutyDay]).then(function (session) {\r\n CourseFactory.getCourseFromStorage(courseId, function (course) {\r\n if (course && !course.HasLimitedInfo && course.CrewCoursePhases && course.CourseTrainees) {\r\n mergeCourseWithSession(course, session, dutyNo, dutyDay, trainingFlightIds, afterRefresh);\r\n }\r\n callback(course);\r\n }, errorCallback);\r\n })\r\n .catch(errorCallback);\r\n };\r\n\r\n\r\n /**\r\n * Remove session By day, dutyNo, dutyDay and courseId\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\r\n function remove(courseId, day, dutyNo, dutyDay, callback, errorCallback) {\r\n IndexedDBService.remove(objType, [day, courseId, dutyNo, dutyDay])\r\n .then(callback)\r\n .catch(errorCallback);\r\n };\r\n\r\n /**\r\n * Get session Trainees By day and courseId\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\r\n function getSessionTrainees(courseId, day, dutyNo, dutyDay, callback, errorCallback) {\r\n IndexedDBService.getById(objType, [day, courseId, dutyNo, dutyDay]).then(function (session) {\r\n var trainees = session && session.trainees ? session.trainees : [];\r\n callback(trainees);\r\n })\r\n .catch(errorCallback);\r\n };\r\n\r\n /**\r\n * Set session\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\r\n function setSession(session, callback, errorCallback) {\r\n IndexedDBService.getById(objType, [session.day, session.courseId, session.dutyNo, session.dutyDay]).then(function (result) {\r\n if (result) {\r\n saveSessionToStorage(session).then(callback).catch(errorCallback);;\r\n } else {\r\n addSessionToStorage(session).then(callback).catch(errorCallback);\r\n }\r\n }).catch(errorCallback);\r\n };\r\n\r\n /**\r\n * Set session\r\n * @memberof FlightSessionFactory\r\n * @param {function} callback \r\n */\r\n function updateSession(trainees, session, courseId, day, dutyNo, dutyDay, callback, errorCallback) {\r\n IndexedDBService.getById(objType, [day, courseId, dutyNo, dutyDay])\r\n .then(function (localSession) {\r\n var isNewSession = false;\r\n if (!localSession) {\r\n localSession = { courseId: courseId, day: day, dutyNo: dutyNo, dutyDay: dutyDay, trainees: [] }\r\n isNewSession = true;\r\n } else {\r\n localSession.trainees = [];\r\n }\r\n\r\n if (session) {\r\n localSession.Media = session.Media;\r\n localSession.ReleasedPhase = session.ReleasedPhase;\r\n localSession.PilotFunctions = session.PilotFunctions;\r\n localSession.TraineeEligibilty = session.TraineeEligibilty;\r\n }\r\n\r\n trainees.forEach(function (trainee) {\r\n localSession.trainees.push(trainee);\r\n });\r\n\r\n if (isNewSession) {\r\n addSessionToStorage(localSession).then(callback).catch(errorCallback);\r\n } else {\r\n saveSessionToStorage(localSession).then(callback).catch(errorCallback);\r\n }\r\n }).catch(errorCallback);\r\n }\r\n\r\n function mergeCourseWithSession(course, session, dutyNo, dutyDay, trainingFlightIds, afterRefresh) {\r\n course.HasLimitedSession = session == undefined;\r\n\r\n var hasPreviousSessions = mergeSyllabusWithHistory(course.CourseTrainees, course.CrewCoursePhases);\r\n filterTraineesByEligibility(dutyNo, dutyDay, course, trainingFlightIds, session, afterRefresh);\r\n \r\n course.CrewCoursePhases.forEach(function (phase) {\r\n calculatePhaseStatus(phase, course);\r\n });\r\n course.selectedPhase = getSelectedPhase(course);\r\n\r\n\r\n // Calculate eligible trainees phase status\r\n course.CourseTrainees.forEach(function (trainee) {\r\n var traineePhase = trainee.Phases.find(x => x.PhaseId == course.selectedPhase.PhaseId);\r\n if (traineePhase) {\r\n trainee.ActivePhaseStatus = traineePhase.PhaseStatus;\r\n }\r\n else {\r\n trainee.ActivePhaseStatus = \"Pending\";\r\n }\r\n trainee.Selectable = trainee.ActivePhaseStatus == \"InProgress\";\r\n });\r\n\r\n // Non InProgress trainees will be marked as NonEligible (remove further ahead trainees on multiple InProgress phases)\r\n course.CourseTrainees.filter(x => !x.Selectable).forEach(function(invalidPhaseTrainee){\r\n invalidPhaseTrainee.EligibilityStatus = false;\r\n invalidPhaseTrainee.EligibilityDesc = \"AlreadySubmitted\";\r\n course.NonEligibleTrainees.push(invalidPhaseTrainee);\r\n });\r\n course.CourseTrainees = course.CourseTrainees.filter(x => x.EligibilityStatus);\r\n \r\n // Get trainee sessions\r\n course.CourseTrainees.forEach(function (trainee) {\r\n var sessionTrainee = session ? session.trainees.find(x => x.CrewId == trainee.CrewId) : null;\r\n if (sessionTrainee) {\r\n trainee.Session = sessionTrainee.Session;\r\n } else {\r\n trainee.Session = {\r\n Released: course.selectedPhase.ModuleType == \"Training\" ? false : true,\r\n CrewId: trainee.CrewId,\r\n Items: [],\r\n Absent: false,\r\n DayGrading: {\r\n Comments: null,\r\n Grade: null,\r\n Competences: []\r\n },\r\n ReleaseGrading: {\r\n Comments: null,\r\n Grade: null,\r\n Competences: []\r\n },\r\n NeedsAdditionalTraining: false,\r\n AdditionalTrainingRemarks: null,\r\n CompleteAdditionalTraining: false\r\n }\r\n }\r\n });\r\n\r\n /* Set default values for release option\r\n Training Modules: 'No' release as default\r\n Check Module: 'Yes' release as default\r\n */\r\n course.ReleasedPhase = course.selectedPhase.ModuleType == \"Training\" ? false : true;\r\n\r\n if (session){\r\n course.Media = session.Media;\r\n course.ReleasedPhase = session.ReleasedPhase;\r\n course.PilotFunctions = session.PilotFunctions;\r\n course.TraineeEligibilty = session.TraineeEligibilty;\r\n }\r\n }\r\n\r\n function getSelectedPhase(course){\r\n var hasSelectedPhase = false;\r\n var phases = course.CrewCoursePhases;\r\n\r\n phases.forEach(function (phase, index, array) {\r\n phase.isFirst = index == 0;\r\n phase.isLast = (index + 1 == array.length);\r\n // Select the first InProgress & selected phase\r\n if (!hasSelectedPhase && phase.Status == \"InProgress\" && phase.isSelected) {\r\n phase.Selected = true;\r\n hasSelectedPhase = true;\r\n }\r\n });\r\n \r\n // Select the first InProgress phase\r\n if (!hasSelectedPhase && phases.some(x => x.Status == \"InProgress\")) {\r\n phases.find(x => x.Status == \"InProgress\").Selected = true;\r\n hasSelectedPhase = true;\r\n }\r\n\r\n if (!hasSelectedPhase) {\r\n phases.find(x => x.isFirst).Selected = true;\r\n }\r\n\r\n var selectedPhase = phases.find(x => x.Selected);\r\n\r\n return selectedPhase;\r\n }\r\n\r\n\r\n function filterTraineesByEligibility(dutyNo, dutyDay, course, trainingFlightIds, session, afterRefresh){\r\n // Trainee Eligiblity cases\r\n // 1. After refresh - Save newly fetched eligibility in session\r\n // 2. No refresh & Session exists - Get last fetched eligibility from session\r\n // 3. No refresh & No session exists - Rely on previously fetched eligibility (different duty - same course)\r\n\r\n var traineeEligibility = course.TraineeEligibilty;\r\n if(!afterRefresh && session && session.TraineeEligibilty){ \r\n traineeEligibility = session.TraineeEligibilty;\r\n }\r\n if(session) session.TraineeEligibilty = traineeEligibility; //update session eligibility\r\n \r\n // Get crew route trainees without any training records\r\n var trainees = getCrewRouteFlightTrainees(dutyNo, dutyDay, trainingFlightIds);\r\n var inactiveTrainees = trainees.filter(x => !course.CourseTrainees.some(z => z.CrewId == x.CrewId));\r\n\r\n //Exclude Non valid trainees\r\n var eligibleTraineeIds = Object.keys(traineeEligibility).filter(x => traineeEligibility[x] == \"NotStarted\" || traineeEligibility[x] == \"ValidPhase\" || traineeEligibility[x] == \"FailedCertificate\").map(Number);\r\n // traineeEligibility[x] == \"UnderAdditionalTraining\" |\r\n var eligibleTrainees = inactiveTrainees.filter(x => eligibleTraineeIds.includes(x.CrewId));\r\n eligibleTrainees.forEach(function (trainee) { trainee.EligibilityStatus = true });\r\n createNewPhaseTrainees(dutyNo, dutyDay, trainingFlightIds, course, eligibleTrainees);\r\n \r\n // Merge eligibleTrainees (inactive) with CourseTrainees (eligible & active)\r\n course.CourseTrainees.forEach(function (trainee) { trainee.EligibilityStatus = true });\r\n course.CourseTrainees.push(...eligibleTrainees);\r\n \r\n // Non eligible trainees\r\n var nonEligibleTrainees = inactiveTrainees.filter(x => !eligibleTraineeIds.includes(x.CrewId));\r\n course.NonEligibleTrainees = nonEligibleTrainees;\r\n\r\n nonEligibleTrainees.forEach(function (trainee) {\r\n trainee.EligibilityStatus = false;\r\n trainee.EligibilityDesc = traineeEligibility[trainee.CrewId];\r\n });\r\n \r\n // Result:\r\n // CourseTrainees = eligible trainees (active or new)\r\n // Non EligibleTrainees\r\n } \r\n\r\n /**\r\n * Create first phase foreach trainee\r\n * @param {object} groundDuty\r\n * @param {object} course\r\n * @param {array} trainees Eligible trainees that haven't yet started training\r\n */\r\n function createNewPhaseTrainees(dutyNo, dutyDay, trainingFlightIds, course, trainees) {\r\n var flights = FlightFactory.getFlightsByDutyNo(dutyNo, dutyDay).filter(f => trainingFlightIds.some(z => z == f.FlightId));\r\n //Match TrainingIndicators with PhaseDutyNos\r\n var crewCoursePhaseDutyNos = [];\r\n var crewrouteTrainingIndicators = [];\r\n course.CrewCoursePhases.forEach(function(coursePhase){\r\n crewCoursePhaseDutyNos = crewCoursePhaseDutyNos.concat(coursePhase.FlightTrainingIndicators);\r\n });\r\n flights.forEach(function(flight){\r\n crewrouteTrainingIndicators.push(flight.TrainingIndicatorId.toString());\r\n });\r\n\r\n var relatedDutyNos = crewCoursePhaseDutyNos.filter(x => crewrouteTrainingIndicators.includes(x));\r\n var relatedPhases = course.CrewCoursePhases.filter(x => x.FlightTrainingIndicators.some(fti => relatedDutyNos.includes(fti)));\r\n\r\n //From related phases, select first in order\r\n relatedPhases = $filter('orderBy')(relatedPhases, 'OrderNo');\r\n var firstPhase = relatedPhases[0];\r\n\r\n trainees.forEach(function (trainee) {\r\n trainee.Phases = [{\r\n PhaseId: firstPhase.PhaseId,\r\n PhaseStatus: \"InProgress\",\r\n RepeatRequestedItems: [],\r\n isSelected: true //selectedPhase\r\n }];\r\n })\r\n }\r\n\r\n function getCrewRouteFlightTrainees(dutyNo, dutyDay, trainingFlightIds) {\r\n var flights = FlightFactory.getFlightsByDutyNo(dutyNo, dutyDay).filter(f => trainingFlightIds.some(z => z == f.FlightId));\r\n var trainees = [];\r\n flights.forEach(function(flight){\r\n flight.crew.filter(x => x.IsTrainee).forEach(function(trainee){\r\n if(!trainees.some(x => x.id == trainee.id)){ //do not push duplicates : trainees that are in multiple flights\r\n trainees.push(trainee);\r\n }\r\n });\r\n });\r\n\r\n trainees.forEach(function(trainee){\r\n trainee.CrewId = trainee.id;\r\n trainee.Id = trainee.id;\r\n trainee.Name = trainee.name;\r\n trainee.AimsId = trainee.aimsId;\r\n\r\n });\r\n return trainees;\r\n }\r\n\r\n function calculatePhaseStatus(phase, course) {\r\n course.CourseTrainees.forEach(function (trainee) {\r\n var traineePhase = trainee.Phases.find(x => x.PhaseId == phase.PhaseId);\r\n if (traineePhase && traineePhase.PhaseStatus == \"InProgress\") {\r\n phase.Status = \"InProgress\";\r\n } else if (!traineePhase && phase.Status != \"InProgress\") {\r\n phase.Status = \"Pending\";\r\n } else if (traineePhase && traineePhase.PhaseStatus == \"Completed\" && phase.Status != \"InProgress\") {\r\n phase.Status = \"Completed\";\r\n }\r\n \r\n //Selected phase, If at least one trainee has it selected\r\n if(traineePhase && !phase.isSelected){\r\n phase.isSelected = traineePhase.isSelected;\r\n }\r\n });\r\n\r\n }\r\n\r\n function mergeSyllabusWithHistory(trainees, phases) {\r\n var flatSullabusItems = [];\r\n trainees.forEach(function (trainee) {\r\n trainee.Phases.forEach(function (phase) {\r\n phase.Sessions.forEach(function (session) {\r\n session.Items.forEach(function (item) {\r\n var flatItem = createFlatHistorySullabusItem(trainee, phase, session, item);\r\n flatSullabusItems.push(flatItem);\r\n });\r\n });\r\n });\r\n });\r\n\r\n phases.filter(x => x.Syllabus).forEach(function (phase, index, array) {\r\n phase.Syllabus.SyllabusItems.forEach(function (syllabusItem) {\r\n syllabusItem.History = flatSullabusItems.filter(item => item.ItemId == syllabusItem.Id);\r\n })\r\n });\r\n var hasPreviousSessions = flatSullabusItems.length > 0;\r\n\r\n return hasPreviousSessions;\r\n }\r\n\r\n function createFlatHistorySullabusItem(trainee, phase, session, item) {\r\n var flatItem =\r\n {\r\n CrewId: trainee.CrewId,\r\n PhaseId: phase.PhaseId,\r\n SessionId: session.SessionId,\r\n SessionComments: session.SessionComments,\r\n SubmissionDate: item.SubmissionDate,\r\n RepeatRequired: item.RepeatRequired,\r\n Tries: item.Tries,\r\n ItemId: item.SyllabusItemId,\r\n Grade: session.Grade,\r\n GradeType: session.GradeType,\r\n InstructorName: session.InstructorName,\r\n InstructorAimsId: session.InstructorAimsId\r\n };\r\n return flatItem;\r\n }\r\n\r\n /**\r\n * Add Session to Storage\r\n * @memberof FlightSessionFactory\r\n * @param {object} Session\r\n */\r\n function addSessionToStorage(session) {\r\n return IndexedDBService.add(objType, session);\r\n };\r\n\r\n /**\r\n * Update Session to Storage\r\n * @memberof FlightSessionFactory\r\n * @param {object} Session\r\n */\r\n function saveSessionToStorage(session) {\r\n return IndexedDBService.put(objType, session);\r\n };\r\n\r\n function submitSession(submittedSession, callback) {\r\n var traingingApiURL = apiUrl + '/Training/SubmitTraining';\r\n return $http.post(traingingApiURL, submittedSession, { 'Content-Type': 'application/json' })\r\n .then(callback);\r\n } \r\n \r\n function applyTraineeInfoToSession(course, courseId, day, dutyNo, dutyDay, callback, errorCallback){\r\n IndexedDBService.getById(objType, [day, courseId, dutyNo, dutyDay])\r\n .then(function (localSession) {\r\n var isNewSession = false;\r\n if (!localSession) {\r\n localSession = { \r\n courseId: courseId, \r\n day: day, \r\n dutyNo: dutyNo, \r\n dutyDay: dutyDay, \r\n trainees: [],\r\n TraineeEligibilty : course.TraineeEligibilty,\r\n CourseTrainees : course.CourseTrainees\r\n };\r\n isNewSession = true;\r\n } else {\r\n localSession.CourseTrainees = course.CourseTrainees;\r\n localSession.TraineeEligibilty = course.TraineeEligibilty;\r\n }\r\n\r\n if (isNewSession) {\r\n addSessionToStorage(localSession).then(callback).catch(errorCallback);\r\n } else {\r\n saveSessionToStorage(localSession).then(callback).catch(errorCallback);\r\n }\r\n }).catch(errorCallback);\r\n }\r\n return service;\r\n }\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('grading', grading);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name grading\r\n * @restrict E\r\n * @description\r\n * Implementation of overall grading\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function grading() {\r\n function link(scope, element, attrs) {\r\n\r\n scope.getRemainingCharacters = getRemainingCharacters;\r\n scope.validateGrading = validateGrading;\r\n scope.filterValidTrainees = filterValidTrainees;\r\n scope.filterTrainee = filterTrainee;\r\n scope.saveComment = saveComment;\r\n \r\n scope.isDayGrading = scope.type == \"day\";\r\n scope.hasCertificateExam = scope.type == \"certificate\";\r\n\r\n scope.isCheck = scope.phase == \"Check\";\r\n\r\n //Separate DayGrading and ReleaseGrading \r\n scope.sessions = [];\r\n scope.trainees.filter(x => !x.Session.Absent).forEach(function(trainee){\r\n var session = scope.isDayGrading ? trainee.Session.DayGrading : trainee.Session.ReleaseGrading;\r\n session.Name = trainee.Name;\r\n session.AimsId = trainee.AimsId;\r\n session.CrewId = trainee.CrewId;\r\n\r\n if(scope.isDayGrading || (!scope.isDayGrading && !scope.isCheck && trainee.AvailableRelease) || (!scope.isDayGrading && scope.isCheck)){\r\n scope.sessions.push(session);\r\n }\r\n });\r\n\r\n \r\n\r\n scope.sessions.forEach(function(traineeSession){\r\n validateGrading(traineeSession);\r\n });\r\n filterValidTrainees();\r\n \r\n\r\n /**\r\n * Calculate remaining characters for comment input\r\n * @param {string} text \r\n * @param {number} max \r\n */\r\n function getRemainingCharacters(text, max) {\r\n if (typeof (text) === \"undefined\" || text === null) return '';\r\n if (typeof (max) === \"undefined\" || max === null || max < 0 || !max) max = 4000;\r\n var length = text.length;\r\n\r\n return 'characters left: ' + (max - length);\r\n }\r\n \r\n function validateGrading(trainee){\r\n trainee.isGradeValid = trainee.Grade != null && trainee.Grade != undefined;\r\n }\r\n\r\n function filterValidTrainees(){\r\n scope.sessions.forEach(function(traineeSession){\r\n traineeSession.isValid = traineeSession.isGradeValid && (!scope.settings.Competences.length || traineeSession.isCompetenceValid); \r\n });\r\n }\r\n\r\n function filterTrainee(){\r\n return function( trainee ) {\r\n var showTrainee = true;\r\n if(scope.selected){ //individual grading view: filter selected\r\n showTrainee = scope.selected.CrewId == trainee.CrewId\r\n }\r\n return showTrainee;\r\n };\r\n }\r\n\r\n function saveComment(){\r\n scope.commentInput();\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/Training/grading.tpl.html',\r\n scope: {trainees:\"=\", settings:\"=\", type:\"@\", phase:\"=\", selected:\"=\", commentInput: \"&onCommentInput\"},\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('GroundCourseCtrl', GroundCourseCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name GroundCourseCtrl\r\n * @description \r\n *\r\n * @ngInject\r\n */\r\n function GroundCourseCtrl($route, $filter, $timeout, TrainingSessionFactory, CrewRouteFactory, FlightFactory, GroundDutyFactory, CourseFactory, $scope, $location, $routeParams) {\r\n $scope.gotoCourse = gotoCourse;\r\n $scope.gotoGroundDuty = gotoGroundDuty;\r\n $scope.stickySelectedTrainee = stickySelectedTrainee;\r\n $scope.toggleView = toggleView;\r\n\r\n $scope.refreshCourse = refresh;\r\n $scope.courseTrainees = [];\r\n\r\n var courseId = Number($routeParams.courseId);\r\n var groundDutyId = Number($routeParams.dutyId);\r\n var groundDuty = GroundDutyFactory.getGroundDutyFromStorage(groundDutyId);\r\n\r\n $scope.isEdit = false;\r\n $scope.loading = false;\r\n $scope.allAbsent = false;\r\n $scope.refreshSuccess = true; //show refresh icon\r\n\r\n if (!groundDuty) {\r\n // go to dashboard if no groundDuty\r\n $location.path(\"/\");\r\n } else {\r\n var date = groundDuty.DutyDateS;\r\n\r\n if (groundDuty.RelatedGroundDuties) {\r\n var courses = GroundDutyFactory.getGroundDutyActiveCourses(groundDutyId);\r\n if (courses.length) {\r\n CourseFactory.getCourseFromStorage(courseId, function(dutyCourse) {\r\n $scope.dutyCourse = dutyCourse;\r\n initCourse(false);\r\n });\r\n }\r\n }\r\n $scope.groundDuty = groundDuty;\r\n $scope.groundDutyId = groundDutyId;\r\n }\r\n\r\n\r\n function initCourse(afterRefresh) {\r\n var courseId = $scope.dutyCourse.Id;\r\n TrainingSessionFactory.getSession(courseId, date, groundDutyId, afterRefresh, function(course) {\r\n if (course && !course.HasLimitedInfo) {\r\n $scope.availableCourse = true;\r\n\r\n $scope.selectedPhase = course.selectedPhase;\r\n $scope.trainees = course.CourseTrainees; //only eligible trainees\r\n course.SequenceWarning = false;\r\n }\r\n\r\n $scope.course = course;\r\n\r\n manageCourseStatus($scope.dutyCourse, course, afterRefresh);\r\n toggleView('History'); //default\r\n\r\n if ($scope.trainees) {\r\n applyAttendanceFromGroundDuty(groundDuty, $scope.trainees);\r\n stickySelectedTrainee();\r\n if($scope.trainees.length && !$scope.trainees.some(x => !x.Session.Absent)){\r\n $scope.allAbsent = true;\r\n }\r\n\r\n //Check for status change (new trainees found on a submitted session (reset) || failed certificate trainees want to retake the test)\r\n if (afterRefresh && $scope.isCourseComplete && $scope.trainees.length) {\r\n GroundDutyFactory.setCoursePending(groundDutyId, courseId);\r\n $scope.isCourseComplete = false;\r\n $route.reload();\r\n }\r\n }\r\n\r\n $scope.reload = false;\r\n $timeout(function() {\r\n $scope.reload = true;\r\n }, 100);\r\n\r\n });\r\n }\r\n\r\n function applyAttendanceFromGroundDuty(groundDuty, trainees){\r\n groundDuty.Trainees.forEach(function(related){\r\n related.CrewMembers.forEach(function(crew){\r\n var trainee = trainees.find(x => x.CrewId == crew.Id);\r\n if(trainee){\r\n trainee.Session.Absent = crew.Absent;\r\n }\r\n });\r\n });\r\n }\r\n\r\n function gotoCourse(course) {\r\n $location.path('/course/' + course.Id + '/' + groundDuty.DutyDateS + \"/\" + groundDuty.Id);\r\n }\r\n\r\n function refresh() {\r\n $scope.loading = true;\r\n\r\n if ($scope.isOffline) {\r\n $timeout(function() {\r\n $scope.loading = false;\r\n }, 100);\r\n $scope.refreshSuccess = false;\r\n $scope.availableCourseInfo = false;\r\n $scope.refreshErrorMsg = \"Online mode is required in order to get course. Please connect to the internet and try again.\";\r\n } else {\r\n CourseFactory.updateCourseInfo($scope.dutyCourse.Id, groundDutyId, function() {\r\n $scope.loading = false;\r\n $scope.refreshSuccess = true;\r\n $scope.availableCourseInfo = true;\r\n\r\n initCourse(true);\r\n $scope.reload = false;\r\n $timeout(function() {\r\n $scope.reload = true;\r\n }, 100);\r\n\r\n },\r\n function() {\r\n $scope.loading = false;\r\n $scope.refreshSuccess = false;\r\n $scope.availableCourseInfo = false;\r\n $scope.refreshErrorMsg = \"Something went wrong! Please Try again.\";\r\n },\r\n function(error) {\r\n console.log(error);\r\n $scope.loading = false;\r\n $scope.refreshSuccess = false;\r\n $scope.availableCourseInfo = false;\r\n\r\n $scope.refreshErrorMsg = \"Oops! Something went wrong!\";\r\n\r\n //null exception!\r\n // if (error.data.errorMessage) {\r\n // $scope.refreshErrorMsg = error.data.errorMessage;\r\n // }\r\n }\r\n )\r\n }\r\n }\r\n\r\n\r\n function manageCourseStatus(dutyCourse, course, afterRefresh) {\r\n // COMPLETED : has been submitted\r\n var isCourseComplete = courses.find(x => x.CourseId == dutyCourse.Id && x.Status == \"Completed\") != null;\r\n\r\n // NEEDS SUBMIT : 1 hour has passed since the end of the course\r\n var now = moment.utc();\r\n if (!dutyCourse.IsCompleted) {\r\n var needsSubmit = false;\r\n var fetched = moment.utc(groundDuty.DutyEnd);\r\n var duration = moment.duration(now.diff(fetched)).asHours();\r\n if (duration > 1) {\r\n needsSubmit = true;\r\n }\r\n }\r\n\r\n // LIMITED : no info available\r\n var isCourseLimited = !course || course.HasLimitedInfo || (course.HasLimitedSession && !afterRefresh);\r\n\r\n // OUTDATED : NeedsRefresh || 18 hours since last refresh\r\n var isCourseOutdated = false;\r\n if (course && course.FetchedTime) {\r\n var now = moment.utc();\r\n var fetched = moment.utc(course.FetchedTime);\r\n var duration = moment.duration(now.diff(fetched)).asHours();\r\n\r\n if (duration > 18 || course.NeedsRefresh) {\r\n isCourseOutdated = true;\r\n }\r\n }\r\n\r\n // ADDITIONAL TRAINING : One trainee, at least, is under additional training\r\n var hasAdditionalTrainingRequest = false;\r\n // if (course.selectedPhase.NeedsAdditionalTraining) \r\n // hasAdditionalTrainingRequest = true; \r\n // course.hasAdditionalTrainingRequest = true;\r\n\r\n $scope.headerMsg = \"Refresh Course\";\r\n if (isCourseLimited) $scope.headerMsg = \"Fetch Course\";\r\n\r\n\r\n $scope.hasPendingTraining = !isCourseComplete;\r\n $scope.hasUnsetTraining = needsSubmit;\r\n $scope.isCourseLimited = isCourseLimited;\r\n $scope.isCourseComplete = isCourseComplete;\r\n $scope.isCourseOutdated = isCourseOutdated;\r\n $scope.hasNotifications = isCourseLimited || isCourseOutdated || isCourseComplete;\r\n $scope.hasAdditionalTrainingRequest = hasAdditionalTrainingRequest;\r\n }\r\n\r\n function gotoGroundDuty() {\r\n $location.path('/groundDuty/' + groundDutyId);\r\n }\r\n\r\n function stickySelectedTrainee(){\r\n var availableRelease = $scope.selectedPhase.ModuleType==\"Check\" || !$scope.trainees.filter(x => !x.Session.Absent).some(tr => tr.Session.Items.some(i => i.Status == \"Pending\"));\r\n var individualGrading = $scope.trainees && $scope.trainees.filter(x => !x.Session.Absent).length && $scope.selectedPhase && \r\n ( ($scope.selectedPhase.Syllabus && $scope.selectedPhase.Syllabus.IsGradable) \r\n || $scope.selectedPhase.HasDayGrading \r\n || ($scope.selectedPhase.HasReleaseGrading && availableRelease)\r\n || RequiresTraineeSignature());\r\n\r\n if(individualGrading){\r\n if($scope.trainees.filter(x => !x.Session.Absent).find(x => x.Session.selected)){\r\n $scope.selectedTrainee = $scope.trainees.filter(x => !x.Session.Absent).find(x => x.Session.selected);\r\n }\r\n else{\r\n $scope.selectedTrainee = $scope.trainees.filter(x => !x.Session.Absent)[0];\r\n }\r\n }\r\n else{\r\n $scope.selectedTrainee = null;\r\n }\r\n\r\n if($scope.selectedTrainee) $scope.selectedTraineeBadge = {CrewId:$scope.selectedTrainee.CrewId};\r\n }\r\n\r\n function RequiresTraineeSignature(){\r\n // End of session signature\r\n var endOfSessionSignature = $scope.selectedPhase.DayGrading.TraineeSignature;\r\n\r\n // End of module signature\r\n var endOfModuleSignature = $scope.course.ReleasedPhase && $scope.selectedPhase.ReleaseGrading.TraineeSignature;\r\n\r\n return endOfSessionSignature || endOfModuleSignature;\r\n }\r\n\r\n function toggleView(mode){\r\n $scope.viewMode = mode;\r\n }\r\n }\r\n})();","(function () {\r\n\r\n a3_cabin_reports.directive('instructions', instructions);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name notifications\r\n * @restrict E\r\n * @description\r\n * Show selected module's trainee & instructor instructions\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n\r\n function instructions($filter, $routeParams, $location, UserFactory) {\r\n function link(scope, attrs) {\r\n scope.warningMessageText = \"\";\r\n scope.viewModuleHistory = viewModuleHistory;\r\n\r\n if(!scope.course.isParallel){\r\n var currentActiveOrderNo = scope.selectedPhase.OrderNo;\r\n \r\n scope.course.CrewCoursePhases.forEach(function(phase){\r\n if(phase.OrderNo < currentActiveOrderNo && phase.Status != \"Completed\"){\r\n phase.SequentialWarning = true;\r\n }\r\n\r\n //check if phase has any history\r\n var oldSessions = [];\r\n scope.trainees.filter(x => !x.Session.Absent).forEach(function(trainee){\r\n var historyPhase = trainee.Phases.find(x => x.PhaseId == phase.PhaseId);\r\n if(historyPhase && historyPhase.Sessions) oldSessions = oldSessions.concat(historyPhase.Sessions);\r\n });\r\n\r\n phase.hasHistory = oldSessions.length>0;\r\n });\r\n }\r\n\r\n scope.course.CrewCoursePhases.forEach(function(phase){\r\n phase.StatusClass = '';\r\n \r\n if(phase.SequentialWarning){\r\n phase.StatusClass=\"panel-danger border-left-red\";\r\n phase.BtnClass=\"bg-red text-white\";\r\n }\r\n else if(phase.Status=='InProgress'){\r\n phase.StatusClass=\"border-left-blue\";\r\n phase.TextClass=\"text-blue\";\r\n phase.BtnClass=\"bg-blue text-white\";\r\n }\r\n else if(phase.Status=='Pending'){\r\n phase.StatusClass=\"border-left-gray \";\r\n phase.TextClass=\"text-gray\";\r\n phase.BtnClass=\"bg-gray text-white\";\r\n }\r\n else if(phase.Status=='Completed'){\r\n phase.StatusClass=\"border-left-green\";\r\n phase.TextClass=\"text-green\";\r\n phase.BtnClass=\"bg-green text-white\";\r\n }\r\n\r\n if(phase.PhaseId==scope.selectedPhase.PhaseId){\r\n phase.StatusClass= phase.StatusClass + \" panel-info\";\r\n }\r\n });\r\n\r\n var furtherAheadPhases = [];\r\n furtherAheadPhases = scope.course.CrewCoursePhases.filter(x => x.SequentialWarning);\r\n furtherAheadPhases = $filter('orderBy')(furtherAheadPhases, 'OrderNo');\r\n\r\n if(furtherAheadPhases.length>0){\r\n scope.course.SequenceWarning = true;\r\n scope.warningMessageText = \"\" + furtherAheadPhases[furtherAheadPhases.length-1].Title + \" is not completed. Confirm that you want to continue to \" + scope.selectedPhase.Title +\".\"\r\n }\r\n\r\n scope.traineeInstructions = scope.selectedPhase.TraineeInstructions;\r\n scope.examinerInstructions = scope.selectedPhase.ExaminerInstructions;\r\n\r\n scope.isInstructorView = false;\r\n var traineesAimsIds = scope.trainees.map(x => x.AimsId);\r\n\r\n var user = UserFactory.getUser();\r\n\r\n if(!traineesAimsIds.includes(user.aimsId)){\r\n scope.isInstructorView = true;\r\n }\r\n\r\n scope.status = {\r\n isInstructorOpen: true,\r\n isTraineeOpen: false\r\n }\r\n\r\n scope.continueSubmission = continueSubmission;\r\n scope.cancelSubmission = cancelSubmission;\r\n\r\n function continueSubmission(){\r\n scope.course.SequenceWarning = false;\r\n }\r\n\r\n function cancelSubmission(){\r\n if(scope.isGround){\r\n gotoGroundDuty();\r\n }\r\n else{\r\n gotoCrewRoute();\r\n }\r\n\r\n }\r\n\r\n function gotoGroundDuty() {\r\n $location.path('/groundDuty/' + Number($routeParams.dutyId));\r\n }\r\n\r\n function gotoCrewRoute() {\r\n var dutyNo = scope.crewRouteDuty.DutyNo;\r\n var dutyDay = scope.crewRouteDuty.DutyDay;\r\n $location.path('/crewRoute/' + dutyNo + '/' + dutyDay);\r\n }\r\n\r\n function viewModuleHistory(phaseId){\r\n var courseId = Number($routeParams.courseId);\r\n var dutyId = Number($routeParams.dutyId);\r\n var date = $routeParams.date; \r\n \r\n\r\n if(dutyId) {\r\n $location.path('/groundHistory/' + courseId + '/' + dutyId + '/' + date + '/' + phaseId);\r\n }\r\n else {\r\n var dutyNo = scope.crewRouteDuty.DutyNo;\r\n var dutyDay = scope.crewRouteDuty.DutyDay; \r\n $location.path('/flightHistory/' + courseId + '/' + dutyNo + '/' + dutyDay + '/' + date + '/' + phaseId);\r\n } \r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n templateUrl: \"views/Training/instructions.tpl.html\",\r\n scope : false,\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('ModuleHistoryCtrl', ModuleHistoryCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ModuleHistoryCtrl\r\n * @description \r\n *\r\n * @ngInject\r\n */\r\n function ModuleHistoryCtrl($scope, $routeParams, TrainingSessionFactory, CourseFactory, FlightSessionFactory, $location) {\r\n $scope.rightScroll = rightScroll;\r\n $scope.leftScroll = leftScroll;\r\n $scope.selectedTrainee = selectedTrainee;\r\n $scope.selectedSession = selectedSession;\r\n $scope.gotoCourse = gotoCourse; \r\n\r\n var isGround = false;\r\n if($routeParams.dutyId) {\r\n isGround = true;\r\n var courseId = Number($routeParams.courseId);\r\n var dutyId = Number($routeParams.dutyId);\r\n var date = $routeParams.date;\r\n var phaseId = Number($routeParams.phaseId);\r\n }\r\n else {\r\n var courseId = Number($routeParams.courseId);\r\n var dutyNo = Number($routeParams.dutyNo);\r\n var dutyDay = Number($routeParams.dutyDay);\r\n var date = $routeParams.date;\r\n var phaseId = Number($routeParams.phaseId);\r\n }\r\n\r\n CourseFactory.getCourseFromStorage(courseId, function (course) {\r\n $scope.phase = course.CrewCoursePhases.find(x => x.PhaseId == phaseId);\r\n $scope.course = course; \r\n if(isGround) {\r\n TrainingSessionFactory.getSessionTrainees(courseId, date, dutyId, function (trainees) { \r\n initHistory(trainees); \r\n });\r\n }\r\n else {\r\n FlightSessionFactory.getSessionTrainees(courseId, date, dutyNo, dutyDay, function (trainees) { \r\n initHistory(trainees); \r\n });\r\n }\r\n });\r\n \r\n function initHistory(trainees) {\r\n if (trainees && trainees.length) {\r\n trainees.forEach(function (trainee) {\r\n trainee.HistoryPhase = trainee.Phases.find(x => x.PhaseId == phaseId);\r\n });\r\n $scope.historyTrainees = setHistoryTrainees(trainees);\r\n\r\n $scope.selectedTraineeBadge = {\r\n crewId: trainees[0].CrewId,\r\n traineeSessionId: trainees[0].HistoryPhase.Sessions[0].Id\r\n };\r\n\r\n $scope.selectedSubmittedSessionBadge = {\r\n sessionId: trainees[0].HistoryPhase.Sessions[0].SessionId\r\n };\r\n }\r\n }\r\n\r\n function setHistoryTrainees(trainees){\r\n var historyTrainees = trainees.filter(x => x.HistoryPhase && x.HistoryPhase.Sessions && !x.Session.Absent);\r\n\r\n historyTrainees.forEach(function(trainee){\r\n\r\n trainee.HistoryPhase.hasSectors = trainee.HistoryPhase.Sessions.some(x => x.Sectors && x.Sectors.length>0);\r\n trainee.HistoryPhase.Sessions.forEach(function(session){\r\n session.hasDayGrading = session.DayGrading.Comments || (session.DayGrading.GradeType != 'NotSet' && session.DayGrading.Grade) || session.DayGrading.Competences.length>0;\r\n session.hasReleaseGrading = session.ReleaseGrading.Comments || (session.ReleaseGrading.GradeType != 'NotSet' && session.ReleaseGrading.Grade) || session.ReleaseGrading.Competences.length>0;\r\n session.AcTypes = [...new Set(session.Sectors.map(ses => ses.AcType))];\r\n\r\n //GroupBy AcType\r\n session.SectorsByAcType = [];\r\n session.AcTypes.forEach(function(acType){\r\n var group = {\r\n AcType: acType,\r\n Sectors: session.Sectors.filter(x => x.AcType == acType)\r\n };\r\n session.SectorsByAcType.push(group);\r\n });\r\n });\r\n\r\n setTraineeSummary(trainee.HistoryPhase);\r\n \r\n });\r\n\r\n return historyTrainees;\r\n }\r\n\r\n function setTraineeSummary(phase){\r\n var sectorSummary = [];\r\n var totalSectors = 0;\r\n\r\n //Unique ac types of all sessions\r\n var allAcTypes = [];\r\n phase.Sessions.forEach(function(session){\r\n allAcTypes = allAcTypes.concat(session.AcTypes);\r\n });\r\n\r\n allAcTypes = [...new Set(allAcTypes)];\r\n\r\n //Group by ac type\r\n allAcTypes.forEach(function(acType){\r\n var sectors = [];\r\n phase.Sessions.forEach(function(session){\r\n sectors = sectors.concat(session.Sectors.filter(x => x.AcType == acType));\r\n });\r\n\r\n var sectorGroup = {\r\n AcType: acType,\r\n Sectors: sectors\r\n };\r\n\r\n totalSectors = totalSectors + sectors.length;\r\n sectorSummary.push(sectorGroup);\r\n });\r\n\r\n\r\n phase.SectorSummary = sectorSummary;\r\n phase.TotalSectors = totalSectors;\r\n\r\n }\r\n\r\n function selectedTrainee() { \r\n return function( trainee ) {\r\n var showSession = false;\r\n if (trainee.CrewId === $scope.selectedTraineeBadge.crewId){\r\n showSession = true;\r\n }\r\n return showSession;\r\n };\r\n }\r\n\r\n function selectedSession() { \r\n return function( historyTrainee ) {\r\n var showSession = false;\r\n if (historyTrainee.SessionId === $scope.selectedSubmittedSessionBadge.sessionId){\r\n showSession = true;\r\n }\r\n return showSession;\r\n };\r\n } \r\n\r\n function leftScroll() {\r\n document.querySelector('.horizontal-scroll').scrollLeft -= 500;\r\n }\r\n \r\n function rightScroll() {\r\n document.querySelector('.horizontal-scroll').scrollLeft += 500;\r\n }\r\n\r\n function gotoCourse() {\r\n if(isGround) {\r\n $location.path('/groundcourse/' + Number($routeParams.courseId) + '/' + Number($routeParams.dutyId) + '/' + $routeParams.date);\r\n }\r\n else {\r\n $location.path('/flightcourse/' + Number($routeParams.courseId) + '/' + Number($routeParams.dutyNo) + '/' + Number($routeParams.dutyDay) + '/' + $routeParams.date);\r\n }\r\n \r\n }\r\n\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('nonEligibleTrainees', nonEligibleTrainees);\r\n\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name nonEligibleTrainees\r\n * @restrict E\r\n * @description\r\n * Show trainees that are not eligible for this training session\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject \r\n */\r\n function nonEligibleTrainees(FlightSessionFactory, $routeParams) {\r\n function link(scope) {\r\n\r\n scope.categories = setCategories();\r\n\r\n //Collect duty trainees\r\n var dutyTrainees = [];\r\n if(scope.groundDuty){\r\n scope.groundDuty.Trainees.forEach(function(related) {\r\n related.CrewMembers.forEach(function(trainee) {\r\n dutyTrainees.push(trainee);\r\n });\r\n });\r\n } \r\n else{\r\n var date = $routeParams.date;\r\n var dutyNo = Number($routeParams.dutyNo);\r\n var dutyDay = Number($routeParams.dutyDay);\r\n var crewRouteCourse = scope.crewRouteDuty.Courses.find(x => x.CourseId == scope.course.Id && new moment(x.Date).isSame(date));\r\n var dutyTrainees = FlightSessionFactory.getCrewRouteFlightTrainees(dutyNo, dutyDay, crewRouteCourse.TrainingFlightIds)\r\n }\r\n\r\n if(scope.course && scope.course.CourseTrainees){\r\n categorizeTrainee(dutyTrainees);\r\n }\r\n\r\n \r\n scope.dutyTrainees = dutyTrainees;\r\n\r\n function setCategories() {\r\n var parallelMessage = \"Trainees may have already completed this module\";\r\n var sequentialMessage = \"Trainees have either completed this module or are not yet ready to start it\";\r\n\r\n return [\r\n {\r\n title:\"InvalidPhase\",\r\n msg: scope.course.isParallel ? parallelMessage : sequentialMessage,\r\n trainees:[],\r\n all:false\r\n },\r\n {\r\n title:\"Submitted\",\r\n msg:\"Trainees have already been submitted\",\r\n trainees:[],\r\n all:false\r\n },\r\n {\r\n title:\"RecurrentPeriod\",\r\n msg:\"Trainees have completed the course earlier\",\r\n trainees:[],\r\n all:false\r\n },\r\n {\r\n title:\"InvalidRole\",\r\n msg: \"For this training, flight crew trainees can only be assessed by a flight crew instructor\",\r\n trainees:[],\r\n all:false\r\n }\r\n ];\r\n \r\n }\r\n \r\n function categorizeTrainee(dutyTrainees){\r\n var allEligibilityTrainees = scope.course.CourseTrainees.concat(scope.course.NonEligibleTrainees);\r\n dutyTrainees.forEach(function(dutyTrainee) {\r\n var courseTrainee = allEligibilityTrainees.find(x => x.CrewId == dutyTrainee.Id);\r\n if(courseTrainee){\r\n // if (courseTrainee.ActivePhaseStatus == 'Completed') {\r\n // scope.categories.find(x => x.title==\"Completed\").trainees.push(dutyTrainee);\r\n // }\r\n if (!courseTrainee.EligibilityStatus && courseTrainee.EligibilityDesc=='AlreadySubmitted') {\r\n scope.categories.find(x => x.title ==\"Submitted\").trainees.push(dutyTrainee);\r\n }\r\n if (!courseTrainee.EligibilityStatus && courseTrainee.EligibilityDesc=='InvalidPhase') {\r\n scope.categories.find(x => x.title==\"InvalidPhase\").trainees.push(dutyTrainee);\r\n }\r\n if (!courseTrainee.EligibilityStatus && courseTrainee.EligibilityDesc=='CooldownPending') {\r\n scope.categories.find(x => x.title ==\"RecurrentPeriod\").trainees.push(dutyTrainee);\r\n }\r\n if (!courseTrainee.EligibilityStatus && courseTrainee.EligibilityDesc=='InvalidRole') {\r\n scope.categories.find(x => x.title ==\"InvalidRole\").trainees.push(dutyTrainee);\r\n }\r\n }\r\n }); \r\n\r\n var allCategory = scope.categories.find(x => x.trainees.length == dutyTrainees.length); //all trainees in same category\r\n if(allCategory){\r\n allCategory.all = true;\r\n }\r\n }\r\n\r\n\r\n \r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: true,\r\n templateUrl: \"views/Training/non-eligible-trainees.tpl.html\",\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('NotificationModalCtrl', NotificationModalCtrl)\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name NotificationModalCtrl\r\n * @description \r\n * Shows Show Signature \r\n * @ngInject\r\n */\r\n\r\n function NotificationModalCtrl($scope, $uibModalInstance){\r\n $scope.close = close;\r\n \r\n /**\r\n * Close the modal\r\n * @memberof NotificationModalCtrl\r\n */\r\n function close(){\r\n $uibModalInstance.close( $scope.success);\r\n }\r\n }\r\n})();","(function () {\r\n\r\n a3_cabin_reports.directive('notifications', notifications);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name notifications\r\n * @restrict E\r\n * @description\r\n * Initialize panel with information messages about session's status and necessary actions\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n\r\n function notifications($routeParams) {\r\n function link(scope) {\r\n var info = {\r\n msg: \"\",\r\n border: \"\",\r\n text: \"\",\r\n showHistory: false\r\n };\r\n\r\n var date = $routeParams.date;\r\n scope.filterSession = filterSession;\r\n scope.selectSession = selectSession;\r\n scope.historyAvailable = false;\r\n scope.additionalTrainingRequested = false;\r\n scope.underAdditionalTraining = false;\r\n scope.showReleaseOption = false;\r\n\r\n //If already submitted : show submitted sessions menu and select first [and no additional training is needed]\r\n if(scope.course.SubmittedSessions && scope.course.SubmittedSessions.length){\r\n var submittedDay = scope.course.SubmittedSessions[0].DutyDay;\r\n var isSame = moment(date).isSame(submittedDay);\r\n if(isSame){\r\n scope.course.historyAvailable = true;\r\n scope.historyAvailable = true;\r\n scope.selectedSubmittedSession = { \r\n sessionId: scope.course.SubmittedSessions[0].SessionId \r\n }; \r\n scope.course.SubmittedSessions.forEach(function (submittedSession) {\r\n submittedSession.TraineesSessions.forEach(function (traineeSession) {\r\n scope.additionalTrainingRequested = traineeSession.NeedsAdditionalRequest;\r\n });\r\n });\r\n scope.course.SubmittedSessions.forEach(function (submittedSession){\r\n if(submittedSession.TraineesSessions.some(x => x.IsReleased == false && x.NeedsAdditionalRequest == false)){\r\n scope.showReleaseOption = true;\r\n }; \r\n });\r\n \r\n }\r\n }\r\n\r\n // 1. Check if session has been already submitted \r\n var isCourseComplete = scope.isCourseComplete\r\n if(isCourseComplete){\r\n\r\n info = {\r\n msg : \"Training form already submitted for this day.\",\r\n border : \"border-left-orange\",\r\n text : \"text-orange\",\r\n showHistory: true //show what was submitted in read-only view\r\n };\r\n }\r\n\r\n // 2. Check if course is Outdated\r\n var isCourseOutdated = scope.isCourseOutdated;\r\n if (isCourseOutdated) {\r\n info = {\r\n msg : \"You have an outdated version of this course. Please Refresh Course.\",\r\n border : \"border-left-orange\",\r\n text : \"text-orange\",\r\n showHistory: false\r\n }\r\n }\r\n\r\n // 3. Check if course needs an initial fetch\r\n var isCourseLimited = scope.isCourseLimited;\r\n if (isCourseLimited && !isCourseComplete) {\r\n isCourseLimited = true;\r\n info = {\r\n msg : \"You need to perform an initial fetch to receive all available information.\",\r\n border : \"border-left-blue\",\r\n text : \"text-blue\",\r\n showHistory: false\r\n }\r\n }\r\n\r\n \r\n // Result\r\n scope.info = info;\r\n\r\n /**\r\n * Filter submitted sessions based on selected from the top menu\r\n * @returns if session is currently selected\r\n */\r\n function filterSession() { \r\n return function( traineeSession ) {\r\n var showSessionTrainees = false;\r\n if (traineeSession.SessionId === scope.selectedSubmittedSession.sessionId){\r\n showSessionTrainees = true;\r\n }\r\n return showSessionTrainees;\r\n };\r\n }\r\n\r\n function selectSession(sessionId){\r\n scope.selectedSubmittedSession.sessionId = sessionId;\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n templateUrl: \"views/Training/notifications.tpl.html\",\r\n scope : false,\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('releasableModule', releasableModule);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name releasableModule\r\n * @restrict E\r\n * @description\r\n * Implementation of releasable Module\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function releasableModule(TrainingSessionFactory, $uibModal, $location) {\r\n function link(scope) {\r\n scope.Submit = Submit;\r\n scope.selectedTrainee = selectedTrainee;\r\n scope.toggleTrainee = toggleTrainee;\r\n scope.getRemainingCharacters = getRemainingCharacters;\r\n scope.leftScroll = leftScroll;\r\n scope.rightScroll = rightScroll;\r\n scope.validateGrading = validateGrading;\r\n scope.getTraineeClass = getTraineeClass;\r\n scope.openTraineeSignature = openTraineeSignature;\r\n scope.resetSignature = resetSignature;\r\n scope.close = close;\r\n\r\n var isGround = scope.groundDuty != null && scope.groundDuty != null;\r\n \r\n var phaseId = scope.course.SubmittedSessions[0].PhaseId;\r\n var phase = scope.course.CrewCoursePhases.find(x => x.PhaseId == phaseId);\r\n scope.settings = phase.ReleaseGrading;\r\n \r\n //Collect all trainee sessions that could be released\r\n var trainees = [];\r\n scope.course.SubmittedSessions.forEach(function (session) {\r\n session.TraineesSessions.filter(x => x.CouldBeReleased && !x.NeedsAdditionalRequest && !x.UnderAdditionalTraining && !x.IsStoppedTraineeCourse).forEach(function (traineeSession) {\r\n traineeSession.RadioModel = true; //set default realease option true\r\n trainees.push(traineeSession);\r\n });\r\n });\r\n\r\n if(trainees.length){\r\n initializeTrainees(trainees, phase);\r\n }\r\n\r\n scope.phase = phase;\r\n scope.trainees = trainees;\r\n\r\n function initializeTrainees(trainees, phase){\r\n scope.selectedTraineeBadge = {\r\n crewId: trainees[0].CrewId\r\n }; \r\n\r\n // Set Release Grading\r\n var releaseCompetences = phase.ReleaseGrading.Competences;\r\n releaseCompetences.forEach(function (competence) { \r\n competence.MandatorySub = setSubCompetenceValues(competence.MandatorySubCompetences); \r\n competence.OptionalSub = setSubCompetenceValues(competence.OptionalSubCompetences);\r\n\r\n //Filter out from optional the ones common with mandatory\r\n competence.OptionalSub = competence.OptionalSub.filter(c => !competence.MandatorySub.includes(c));\r\n });\r\n\r\n //Set Trainee Competences\r\n trainees.forEach(function (traineeSession) {\r\n var competences = [];\r\n \r\n releaseCompetences.forEach(function (competence) {\r\n competences.push(JSON.parse(JSON.stringify(competence)));\r\n });\r\n traineeSession.ReleaseGrading.Competences = competences;\r\n });\r\n\r\n //Initialize validation\r\n trainees.forEach(function (traineeSession) {\r\n traineeSession.ReleaseGrading.isGradeValid = scope.settings.GradeType == \"NotSet\";\r\n traineeSession.ReleaseGrading.isReleaseGradingValid = scope.settings.Competences.length == 0;\r\n });\r\n\r\n //For ground: check aircraft visits\r\n if(isGround && phase.AircraftTypes.length){\r\n trainees.forEach(function(trainee){\r\n var visitedAircrafts = trainee.AllVisitedAcTypes;\r\n \r\n var pendingAircrafts = [];\r\n phase.AircraftTypes.forEach(function(type){\r\n var array = type.split(',');\r\n\r\n //if arvi requirement is not met\r\n if (!array.some(x => visitedAircrafts.includes(x))) {\r\n var pendingArviList = [];\r\n if (array.length > 1) \r\n {\r\n array.forEach(function(arvi){\r\n pendingArviList.push(arvi);\r\n });\r\n }\r\n else\r\n {\r\n pendingArviList.push(array[0]);\r\n }\r\n pendingAircrafts.push(pendingArviList);\r\n }\r\n });\r\n\r\n trainee.pendingAircrafts = pendingAircrafts;\r\n trainee.ShowReleaseWarning = trainee.pendingAircrafts.length>0;\r\n });\r\n }\r\n scope.showReleaseWarning = trainees.some(x => x.ShowReleaseWarning);\r\n }\r\n\r\n function selectedTrainee() { \r\n \r\n return function( trainee ) {\r\n var showTrainee = false;\r\n if (trainee.CrewId === scope.selectedTraineeBadge.crewId){\r\n showTrainee = true;\r\n }\r\n return showTrainee;\r\n };\r\n }\r\n\r\n function close() {\r\n scope.modalInstance.close();\r\n }\r\n\r\n function toggleTrainee(){\r\n if(!scope.selectedTraineeBadge.crewId){\r\n scope.selectedTraineeBadge.crewId = scope.trainees.find(x => x.RadioModel).CrewId;\r\n }\r\n\r\n var selectedCrewId = scope.selectedTraineeBadge.crewId;\r\n var selectedTrainee = scope.trainees.find(x => x.CrewId == selectedCrewId);\r\n if(selectedTrainee && !selectedTrainee.RadioModel){\r\n if(scope.trainees.find(x => x.RadioModel)){\r\n scope.selectedTraineeBadge.crewId = scope.trainees.find(x => x.RadioModel).CrewId;\r\n }\r\n else{\r\n scope.selectedTraineeBadge.crewId = null;\r\n }\r\n }\r\n }\r\n\r\n function getTraineeClass(crewId){\r\n var textClass=\"\";\r\n\r\n var trainee = scope.trainees.find(x => x.CrewId == crewId);\r\n \r\n //Validate Release grading\r\n var isReleaseGradingValid = trainee.ReleaseGrading.isGradeValid;\r\n var isReleaseCompetencesValid = trainee.ReleaseGrading.isCompetenceValid;\r\n\r\n if(isReleaseGradingValid && isReleaseCompetencesValid){\r\n textClass = \"bg-green text-white\";\r\n }\r\n else{\r\n textClass = \"bg-amber text-white\";\r\n }\r\n \r\n return textClass;\r\n }\r\n\r\n\r\n function Submit() {\r\n if (!isValidForm()) {\r\n scope.modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgSubmitValidation.html',\r\n scope: scope,\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'lg'\r\n });\r\n }\r\n else {\r\n scope.modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgSign.html',\r\n controller: 'ReleaseSignatureModalCtrl',\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n courseId: function () { return scope.course.Id; },\r\n isGround: function () { return isGround; },\r\n confirmationMsg: function () { return scope.settings.ConfirmationMessage; },\r\n requiresInstructorSignature: function () { return scope.settings.InstructorSignature },\r\n trainees: function () { return scope.trainees.filter(x => x.RadioModel) },\r\n submitRelease: function () { return SubmitRelease; }\r\n }\r\n });\r\n \r\n scope.modalInstance.result.then(function (result) {\r\n if(result.success){\r\n $location.path(\"/\");\r\n }\r\n });\r\n } \r\n }\r\n\r\n function SubmitRelease(password) {\r\n var submittedSessions = {\r\n SignaturePassword : password,\r\n TraineesSessions : trainees.filter(x => x.RadioModel)\r\n };\r\n\r\n return TrainingSessionFactory.releaseSession(submittedSessions);\r\n }\r\n\r\n function validateGrading(trainee){\r\n trainee.ReleaseGrading.isGradeValid = trainee.ReleaseGrading.Grade != null && trainee.ReleaseGrading.Grade != undefined;\r\n }\r\n\r\n /**\r\n * Calculate remaining characters for comment input\r\n * @param {string} text \r\n * @param {number} max \r\n */\r\n function getRemainingCharacters(text, max) {\r\n if (typeof (text) === \"undefined\" || text === null) return '';\r\n if (typeof (max) === \"undefined\" || max === null || max < 0 || !max) max = 4000;\r\n var length = text.length;\r\n\r\n return 'characters left: ' + (max - length);\r\n }\r\n\r\n function setSubCompetenceValues(current) {\r\n var updated = [];\r\n var first = parseInt(current[0], 10);\r\n var last = current[current.length - 1];\r\n\r\n if (first) {\r\n for (var i = first; i <= last; i++) {\r\n updated.push(i);\r\n }\r\n }\r\n return updated;\r\n }\r\n\r\n function leftScroll() {\r\n document.querySelector('.horizontal-scroll').scrollLeft -= 500;\r\n }\r\n \r\n function rightScroll() {\r\n document.querySelector('.horizontal-scroll').scrollLeft += 500;\r\n }\r\n\r\n \r\n function isValidForm() {\r\n /*Requirements before split release\r\n 1. OnLine Mode\r\n 2. Valid Release Grading\r\n 3. Trainee Signature\r\n */\r\n\r\n var selectedTrainee = scope.trainees.find(x => x.CrewId == scope.selectedTraineeBadge.crewId);\r\n\r\n var isValid = false;\r\n var info = {\r\n border: \"\",\r\n icon: \"\",\r\n msg: \"\"\r\n };\r\n\r\n if (!window.navigator.onLine) {\r\n info = {\r\n border: \"border-left-red\",\r\n icon: \"fa-warning text-red\",\r\n msg: \" Online mode is required in order to submit a training.

Check your connection and try again!

\",\r\n };\r\n }\r\n else if(scope.settings.TraineeSignature && scope.trainees.filter(x => x.RadioModel).some(x => !x.Authorized)){\r\n\r\n if(selectedTrainee && !selectedTrainee.Authorized){\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-pencil-square-o text-orange\",\r\n msg: \"\" + selectedTrainee.TraineeName + \" needs to sign the form!\",\r\n scrollToTop:false\r\n };\r\n }\r\n else{\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg: \"All trainees need to sign their forms!\",\r\n scrollToTop:true\r\n };\r\n }\r\n }\r\n else if (!isGradingValid()) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg : \"\"\r\n };\r\n if(selectedTrainee && !selectedTrainee.ReleaseGrading.isCompetenceValid) {\r\n info.msg = \"You need to grade all competences for \" + selectedTrainee.TraineeName + \" before submitting!\"\r\n }\r\n else if(selectedTrainee && !selectedTrainee.ReleaseGrading.isGradeValid){\r\n info.msg = \"You need to grade \" + selectedTrainee.TraineeName + \" before submitting!\"\r\n }\r\n else if(!scope.gradingValidationInfo.isReleaseCompetencesValid || !scope.gradingValidationInfo.isReleaseGradingValid){\r\n info.msg = \"You need to grade all trainees before submitting!\"\r\n }\r\n }\r\n else {\r\n isValid = true;\r\n }\r\n\r\n scope.info = info;\r\n return isValid;\r\n }\r\n\r\n function validateTraineeForm(trainee) {\r\n /*Requirements before trainee signature\r\n 1. OnLine Mode\r\n 2. Valid Trainee Release Grading\r\n */\r\n\r\n var isValid = false;\r\n var info = {\r\n border: \"\",\r\n icon: \"\",\r\n msg: \"\"\r\n };\r\n\r\n if (!window.navigator.onLine) {\r\n info = {\r\n border: \"border-left-red\",\r\n icon: \"fa-warning text-red\",\r\n msg: \" Online mode is required in order to submit a training.

Check your connection and try again!

\",\r\n };\r\n }\r\n else if (!trainee.ReleaseGrading.isCompetenceValid) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg : \"You need to grade all competences!\"\r\n };\r\n }\r\n else if (!trainee.ReleaseGrading.isGradeValid) {\r\n info = {\r\n border: \"border-left-orange\",\r\n icon: \"fa-warning text-orange\",\r\n msg : \"You need to select an overall grade!\"\r\n };\r\n }\r\n else {\r\n isValid = true;\r\n }\r\n\r\n scope.info = info;\r\n return isValid;\r\n }\r\n\r\n function isGradingValid() {\r\n var isReleaseGradingValid = scope.settings.GradeType == \"NotSet\";\r\n var isReleaseCompetencesValid = scope.settings.Competences.length == 0;\r\n\r\n if (!isReleaseGradingValid) isReleaseGradingValid = !scope.trainees.filter(x => x.RadioModel).some(x => !x.ReleaseGrading.isGradeValid);\r\n\r\n if (!isReleaseCompetencesValid) isReleaseCompetencesValid = !scope.trainees.filter(x => x.RadioModel).some(x => !x.ReleaseGrading.isCompetenceValid);\r\n\r\n scope.gradingValidationInfo = {\r\n isReleaseGradingValid: isReleaseGradingValid,\r\n isReleaseCompetencesValid: isReleaseCompetencesValid,\r\n };\r\n\r\n return isReleaseGradingValid && isReleaseCompetencesValid;\r\n }\r\n\r\n\r\n function openTraineeSignature(trainee){\r\n //Enter signature mode : trainee form becomes read-only\r\n if(!trainee.Authorized){\r\n //Trainee can sign only if his form is valid\r\n if (!validateTraineeForm(trainee)) {\r\n scope.modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgSubmitValidation.html',\r\n scope: scope,\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'lg'\r\n });\r\n }\r\n else{\r\n trainee.Session = {Authorized:false};\r\n trainee.Name = trainee.TraineeName;\r\n scope.modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgTraineeSignature.html',\r\n controller: 'TraineeSignatureModalCtrl',\r\n scope: scope,\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n trainee: function () { return trainee; },\r\n signatureSuccess: function () { return function(){trainee.Authorized = true}; }\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n function resetSignature(trainee){\r\n var modalInstance = $uibModal.open({\r\n templateUrl: 'views/Training/dlgResetSignature.html',\r\n controller: 'TraineeSignatureModalCtrl',\r\n scope: scope,\r\n backdrop: 'static',\r\n keyboard: false,\r\n size: 'md',\r\n resolve: {\r\n trainee: function () { return trainee; },\r\n signatureSuccess: function () { return function(){}; }\r\n }\r\n });\r\n\r\n modalInstance.result.then(function (confirm) {\r\n if(confirm){\r\n trainee.Authorized = false;\r\n trainee.Session.Authorized = false;\r\n }\r\n \r\n });\r\n }\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/Training/releasable-module.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n\r\n a3_cabin_reports.directive('releaseWarning', releaseWarning);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name releaseWarning\r\n * @restrict E\r\n * @description\r\n * Soft rules alert in release\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n\r\n function releaseWarning() {\r\n function link(scope, attrs) {\r\n scope.filterSelectedTrainee = filterSelectedTrainee;\r\n scope.warningTrainees = scope.trainees.filter(x => !x.Session.Absent && x.ShowReleaseWarning);\r\n\r\n function filterSelectedTrainee(){\r\n return function( trainee ) {\r\n var showTrainee = false;\r\n if(scope.selectedTrainee){\r\n showTrainee = trainee.CrewId == scope.selectedTrainee.CrewId;\r\n }\r\n return showTrainee;\r\n };\r\n }\r\n\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n templateUrl: \"views/Training/releaseWarning.tpl.html\",\r\n scope : false,\r\n terminal: true,\r\n link: link\r\n }\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('ReleaseSignatureModalCtrl', ReleaseSignatureModalCtrl)\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SignatureModalCtrl\r\n * @description \r\n * Shows Show Signature \r\n * @ngInject\r\n */\r\n\r\n function ReleaseSignatureModalCtrl($scope, $routeParams, CourseFactory, $uibModalInstance, courseId, isGround, confirmationMsg, requiresInstructorSignature, trainees, submitRelease){\r\n $scope.close = close;\r\n $scope.submit = submit;\r\n $scope.confirm = confirm;\r\n $scope.confirmAircraft = confirmAircraft;\r\n\r\n $scope.errorMessage = \"\";\r\n $scope.successMessage = \"\";\r\n $scope.responseText = null;\r\n $scope.responseHasErrors = null;\r\n $scope.success = false;\r\n $scope.isLoading = false;\r\n\r\n $scope.formData = {};\r\n \r\n $scope.requiredSignature = requiresInstructorSignature;\r\n\r\n $scope.isConfirmed = true;\r\n $scope.finalPendigArVis = [];\r\n \r\n if(isGround && hasPendingAircraftVisits()) {\r\n $scope.aircraftVisits = true;\r\n }\r\n else if(confirmationMsg){\r\n $scope.confirmationMsg = confirmationMsg;\r\n $scope.isConfirmed = false;\r\n }\r\n else{\r\n if(!requiresInstructorSignature){ //if signature isn't required continue with submit \r\n $scope.isLoading = true;\r\n submit();\r\n }\r\n }\r\n\r\n function hasPendingAircraftVisits() {\r\n var released = trainees.filter(x => x.RadioModel)\r\n var pendingVisits = released.some(x => x.pendingAircrafts && x.pendingAircrafts.length > 0);\r\n\r\n if(pendingVisits){ \r\n var maxLength = 0;\r\n released.forEach(function(trainee){\r\n if(trainee.pendingAircrafts.length > maxLength){\r\n var maxList = trainee.pendingAircrafts;\r\n maxLength = maxList.length; \r\n $scope.finalPendigArVis = trainee.pendingAircrafts; \r\n } \r\n });\r\n }\r\n return pendingVisits;\r\n }\r\n\r\n function confirm(){\r\n $scope.isConfirmed = true;\r\n if(!requiresInstructorSignature){ //if signature isn't required continue with submit \r\n $scope.isLoading = true;\r\n submit();\r\n }\r\n }\r\n\r\n function confirmAircraft() {\r\n $scope.aircraftVisits = false;\r\n if(confirmationMsg){\r\n $scope.confirmationMsg = confirmationMsg;\r\n $scope.isConfirmed = false;\r\n } \r\n }\r\n\r\n function submit(){\r\n $scope.errorMessage = \"\";\r\n $scope.successMessage = \"\";\r\n \r\n $scope.isLoading = true;\r\n $scope.success = false;\r\n\r\n var signaturePassword = $scope.formData.password;\r\n if(!signaturePassword && requiresInstructorSignature){\r\n $scope.isLoading = false;\r\n $scope.errorMessage = \"Signature is required. Please enter your password.\";\r\n }else{\r\n\r\n submitRelease(signaturePassword).then(function(data){\r\n $scope.isLoading = false;\r\n var errorMessage = data.data.errorMessage;\r\n\r\n $scope.successMessage = \"Training has been submitted.\"\r\n\r\n //always show errorMessage even if success is true\r\n if(errorMessage && errorMessage.length > 0){\r\n $scope.errorMessage = errorMessage;\r\n\r\n //not Release Trainees\r\n var responseTrainees = data.data.data.data;\r\n var responseTraineeCrewIds = responseTrainees.map(function(trainee){return trainee.CrewId});\r\n $scope.traineeInfo = trainees.filter(x => responseTraineeCrewIds.includes(x.CrewId));\r\n }\r\n else{\r\n $scope.errorMessage = null;\r\n }\r\n\r\n CourseFactory.setCourseOutdated(courseId);\r\n $scope.success = true;\r\n }).catch(function(data){\r\n $scope.isLoading = false;\r\n if(data.data && data.data.errorMessage){\r\n $scope.errorMessage = data.data.errorMessage;\r\n }\r\n else{\r\n $scope.errorMessage = \"Failed to save Training Session\";\r\n }\r\n }); \r\n }\r\n\r\n // clear password\r\n\t\t $scope.formData.password = \"\";\r\n }\r\n\r\n /**\r\n * Close the modal\r\n * @memberof SignModalCtrl\r\n */\r\n function close(){\r\n var result = {\r\n \"success\" : $scope.success\r\n };\r\n $uibModalInstance.close(result);\r\n }\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('SignatureModalCtrl', SignatureModalCtrl)\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SignatureModalCtrl\r\n * @description \r\n * Shows Show Signature \r\n * @ngInject\r\n */\r\n\r\n function SignatureModalCtrl($scope, $routeParams, $uibModalInstance, TrainingSessionFactory, FlightSessionFactory, GroundDutyFactory, CrewRouteFactory, CourseFactory, courseId, date, dutyId, dutyNo, dutyDay, confirmationMsg, requiresInstructorSignature, trainees, submitSession, releaseGrading, isReleased, needsAdditionalTraining){\r\n $scope.close = close;\r\n $scope.submit = submit;\r\n $scope.confirm = confirm;\r\n $scope.confirmSubmit = confirmSubmit;\r\n $scope.releaseSubmit = releaseSubmit;\r\n $scope.confirmAircraft = confirmAircraft;\r\n\r\n $scope.errorMessage = \"\";\r\n $scope.successMessage = \"\";\r\n $scope.responseText = null;\r\n $scope.responseHasErrors = null;\r\n $scope.success = false;\r\n $scope.isLoading = false;\r\n $scope.withGrading = false;\r\n\r\n $scope.formData = {};\r\n \r\n var requiredSignature = requiresInstructorSignature;\r\n $scope.requiredSignature = requiredSignature;\r\n\r\n $scope.releaseWarning = false;\r\n $scope.isConfirmed = true;\r\n $scope.releaseGrading = releaseGrading;\r\n $scope.finalPendigArVis = [];\r\n $scope.needsAdditionalTraining = needsAdditionalTraining;\r\n\r\n var isGroundDuty = false;\r\n if(dutyId) {\r\n isGroundDuty = true;\r\n }\r\n\r\n if(releaseNotSelected()){\r\n $scope.releaseWarning = true; \r\n }\r\n else if(isGroundDuty && hasPendingAircraftVisits()) {\r\n $scope.aircraftVisits = true;\r\n }\r\n else if(confirmationMsg && isReleased){\r\n $scope.confirmationMsg = confirmationMsg;\r\n $scope.isConfirmed = false;\r\n }\r\n else{\r\n if(!requiresInstructorSignature){ //if signature isn't required continue with submit \r\n $scope.isLoading = true;\r\n submit();\r\n }\r\n }\r\n\r\n function releaseNotSelected(){\r\n var allAvailable = !trainees.filter(x => !x.Session.Absent).some(x => !x.AvailableRelease);\r\n var notReleased = trainees.filter(x =>!x.Session.Absent).some(x => !x.Session.Released);\r\n return allAvailable && notReleased;\r\n }\r\n\r\n function hasPendingAircraftVisits() {\r\n var released = !trainees.filter(x =>!x.Session.Absent).some(x => !x.Session.Released) || $scope.withGrading;\r\n var pendingVisits = released && trainees.filter(x => !x.Session.Absent).some(x => x.pendingAircrafts && x.pendingAircrafts.length > 0);\r\n\r\n if(pendingVisits){ \r\n var maxLength = 0;\r\n trainees.filter(x => !x.Session.Absent).forEach(function(trainee){\r\n if(trainee.pendingAircrafts.length > maxLength){\r\n var maxList = trainee.pendingAircrafts;\r\n maxLength = maxList.length; \r\n $scope.finalPendigArVis = trainee.pendingAircrafts; \r\n } \r\n });\r\n }\r\n return pendingVisits;\r\n }\r\n\r\n function confirm(){\r\n $scope.isConfirmed = true;\r\n if(!requiresInstructorSignature){ //if signature isn't required continue with submit \r\n $scope.isLoading = true;\r\n submit();\r\n }\r\n }\r\n\r\n function confirmSubmit(){\r\n $scope.releaseWarning = false;\r\n if(isGroundDuty && hasPendingAircraftVisits()){\r\n $scope.aircraftVisits = true;\r\n } \r\n }\r\n\r\n function confirmAircraft() {\r\n $scope.aircraftVisits = false;\r\n if(confirmationMsg){\r\n $scope.confirmationMsg = confirmationMsg;\r\n $scope.isConfirmed = false;\r\n } \r\n }\r\n\r\n function releaseSubmit(){\r\n $scope.withGrading = true;\r\n $scope.releaseWarning = false;\r\n\r\n if(hasPendingAircraftVisits()){\r\n $scope.aircraftVisits = true;\r\n } \r\n else if(confirmationMsg){\r\n $scope.confirmationMsg = confirmationMsg;\r\n $scope.isConfirmed = false;\r\n } \r\n }\r\n\r\n function submit(){\r\n $scope.errorMessage = \"\";\r\n $scope.successMessage = \"\";\r\n \r\n $scope.isLoading = true;\r\n $scope.success = false;\r\n\r\n var signaturePassword = $scope.formData.password;\r\n if(!signaturePassword && requiredSignature){\r\n $scope.isLoading = false;\r\n $scope.errorMessage = \"Signature is required. Please enter your password.\";\r\n }else{\r\n\r\n submitSession(signaturePassword, $scope.withGrading).then(function(data){\r\n $scope.isLoading = false;\r\n var errorMessage = data.data.errorMessage;\r\n\r\n $scope.successMessage = \"Training has been submitted.\"\r\n\r\n //always show errorMessage even if success is true\r\n if(errorMessage && errorMessage.length > 0){\r\n $scope.errorMessage = errorMessage;\r\n\r\n //not Release Trainees\r\n var responseTrainees = data.data.data.data;\r\n var responseTraineeCrewIds = responseTrainees.map(function(trainee){return trainee.CrewId});\r\n $scope.traineeInfo = trainees.filter(x => responseTraineeCrewIds.includes(x.CrewId));\r\n }\r\n else{\r\n $scope.errorMessage = null;\r\n }\r\n\r\n if(dutyId){ //isGround\r\n TrainingSessionFactory.remove(courseId,date,dutyId);\r\n GroundDutyFactory.setCourseCompleted(dutyId,courseId);\r\n }\r\n else{ //isFlight\r\n FlightSessionFactory.remove(courseId, date, dutyNo, dutyDay);\r\n CrewRouteFactory.setCourseCompleted(dutyNo, dutyDay, courseId, date)\r\n }\r\n\r\n CourseFactory.setCourseOutdated(courseId);\r\n $scope.success = true;\r\n }).catch(function(data){\r\n $scope.isLoading = false;\r\n if(data.data && data.data.errorMessage){\r\n $scope.errorMessage = data.data.errorMessage;\r\n }\r\n else{\r\n $scope.errorMessage = \"Failed to save Training Session\";\r\n }\r\n }); \r\n }\r\n\r\n // clear password\r\n\t\t $scope.formData.password = \"\";\r\n }\r\n\r\n /**\r\n * Close the modal\r\n * @memberof SignModalCtrl\r\n */\r\n function close(){\r\n var result = {\r\n \"success\" : $scope.success\r\n };\r\n $uibModalInstance.close(result);\r\n }\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('syllabusItemHeader', syllabusItemHeader);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name syllabusItemHeader\r\n * @restrict E\r\n * @description\r\n * Panel heading for syllabus items\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function syllabusItemHeader() {\r\n function link(scope, element, attrs) {\r\n scope.selectTry = selectTry;\r\n scope.selectGrading = selectGrading;\r\n\r\n //find first not ReadOnly try\r\n scope.pendingAttempt = scope.item.Tries.find(x => x.isFirstTry);\r\n scope.firstTry = scope.item.Tries[0];\r\n\r\n\r\n function selectTry(){\r\n if(scope.pendingAttempt){\r\n scope.itemSelection();\r\n }\r\n }\r\n \r\n function selectGrading(){\r\n scope.gradingSelection();\r\n }\r\n\r\n }\r\n\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/Training/syllabus-item-header.tpl.html',\r\n scope: {item:\"=\", itemSelection: \"&onItemSelection\", gradingSelection: \"&onGradingSelection\"},\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.directive('syllabus', syllabus);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name certificates\r\n * @restrict E\r\n * @description\r\n * Implementation of syllabus\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */\r\n function syllabus(TrainingSessionFactory, FlightSessionFactory, $timeout) {\r\n function link(scope, element, attrs) {\r\n\r\n var isGround = false;\r\n var courseId = scope.dutyCourse.Id;\r\n\r\n if (scope.groundDuty) {\r\n isGround = true;\r\n var date = scope.groundDuty.DutyDateS;\r\n var dutyId = scope.groundDuty.Id;\r\n }\r\n else {\r\n var date = scope.crewRouteDuty.date;\r\n var dutyNo = scope.crewRouteDuty.DutyNo;\r\n var dutyDay = scope.crewRouteDuty.DutyDay;\r\n }\r\n\r\n scope.updateTraineesSyllabus = updateTraineesSyllabus;\r\n scope.selectTry = selectTry;\r\n scope.updateTry = updateTry;\r\n scope.oneAtATime = true;\r\n scope.addTry = addTry;\r\n scope.removeTry = removeTry;\r\n scope.setPanelStyle = setPanelStyle;\r\n scope.selectTryFromHeader = selectTryFromHeader;\r\n scope.gradeFromHeader = gradeFromHeader;\r\n\r\n scope.nonGradableSyllabus = scope.traineeSyllabi[0].Items.every(item => !item.IsGradable);\r\n scope.personalizedRemarks = false;\r\n scope.showPersonalizedRemarks = false;\r\n scope.personalizedRemarksChanged = personalizedRemarksChanged;\r\n scope.addTraineeRemarksRow = addTraineeRemarksRow;\r\n scope.traineesPersonalizedRemarks = [];\r\n scope.updatePersonalizeRemarks = updatePersonalizeRemarks;\r\n scope.deleteTraineeRemarks = deleteTraineeRemarks;\r\n scope.isAddRemarksButtonDisabled = isAddRemarksButtonDisabled;\r\n scope.traineeValueChanged = traineeValueChanged;\r\n scope.hasSelectedTrainee = false;\r\n\r\n scope.traineeSyllabi.forEach(function (traineeSyllabus) {\r\n traineeSyllabus.Items.forEach(function (syllabusItem) {\r\n syllabusItem.usePersonalizedRemarks = false;\r\n syllabusItem.traineesPersonalizedRemarks = [];\r\n syllabusItem.Tries.forEach(function (attempt) {\r\n //Check if default grade exists & set status\r\n if (syllabusItem.IsGradable && !attempt.isReadOnly) {\r\n itemAutoSelection(syllabusItem, attempt); //select item depending on grade existence\r\n }\r\n });\r\n setPanelStyle(syllabusItem); //ui depending on validation & status\r\n updateTraineesSyllabus(syllabusItem, traineeSyllabus); //copy values to all trainee syllabi \r\n });\r\n });\r\n\r\n //Multiple syllabi - Get session to store competence grading\r\n if (scope.traineeSyllabi.length > 1) {\r\n scope.traineeSyllabi.forEach(function (traineeSyllabus) {\r\n var crewId = traineeSyllabus.TraineeIds[0];\r\n var trainee = scope.trainees.find(x => x.CrewId == crewId);\r\n traineeSyllabus.TraineeName = trainee.Name;\r\n traineeSyllabus.TraineeAimsId = trainee.AimsId;\r\n });\r\n }\r\n\r\n\r\n function gradeFromHeader(syllabus, syllabusItem) {\r\n var firstPendingTry = syllabusItem.Tries.filter(x => !x.isReadOnly)[0];\r\n updateTry(syllabus, syllabusItem, firstPendingTry);\r\n setPanelStyle(syllabusItem);\r\n updateTraineesSyllabus(syllabusItem, syllabus);\r\n\r\n triggerSyllabusClick();\r\n }\r\n\r\n function selectTryFromHeader(syllabus, syllabusItem) {\r\n var firstPendingTry = syllabusItem.Tries.filter(x => !x.isReadOnly)[0];\r\n selectTry(syllabus, syllabusItem, firstPendingTry);\r\n\r\n if (isGround) {\r\n TrainingSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyId, console.log, function (e) { console.log(e) })\r\n }\r\n else {\r\n FlightSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyNo, dutyDay, console.log, function (e) { console.log(e) })\r\n }\r\n\r\n triggerSyllabusClick();\r\n }\r\n\r\n function triggerSyllabusClick() {\r\n //preventDefault() and stopPropagation() prevents setReleaseStatus() to be triggered\r\n $timeout(function () {\r\n var el = document.getElementById('syllabus');\r\n angular.element(el).triggerHandler('click');\r\n }, 0);\r\n }\r\n\r\n function selectTry(syllabus, syllabusItem, attempt) {\r\n attempt.Selected = !attempt.Selected;\r\n syllabusItem.Selected = syllabusItem.Tries.filter(t => !t.isReadOnly).some(t => t.Selected);\r\n\r\n setPanelStyle(syllabusItem);\r\n updateTraineesSyllabus(syllabusItem, syllabus);\r\n }\r\n\r\n function updateTry(syllabus, syllabusItem, attempt) { \r\n if (syllabusItem.IsGradable) {\r\n itemAutoSelection(syllabusItem, attempt); //select item depending on grade existence\r\n }\r\n setPanelStyle(syllabusItem); //ui depending on validation & status\r\n updateTraineesSyllabus(syllabusItem, syllabus); //copy values to all trainee syllabi \r\n updateSession(); //save in IndexDb\r\n }\r\n\r\n function itemAutoSelection(syllabusItem, attempt) {\r\n var hasCompetencesGrading = attempt.TryGrading.Competences.some(x => x.Grading);\r\n if (attempt.TryGrading.Grade || hasCompetencesGrading) {\r\n attempt.Selected = true;\r\n syllabusItem.Selected = true;\r\n }\r\n else {\r\n attempt.Selected = false;\r\n syllabusItem.Selected = false;\r\n\r\n //Check if any of the tries has grading - If not, deselect item\r\n var pendingTries = syllabusItem.Tries.filter(x => !x.isReadOnly); //filter out history tries\r\n for (var i = 0; i < pendingTries.length; i++) {\r\n var itemTry = pendingTries[i];\r\n var tryCompetenceGrading = itemTry.TryGrading.Competences.some(x => x.Grading);\r\n if (itemTry.TryGrading.Grade || tryCompetenceGrading) {\r\n syllabusItem.Selected = true;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n function setPanelStyle(item) {\r\n var historyTriesCount = item.Tries.filter(x => x.isReadOnly).length;\r\n var newTriesCount = item.Tries.filter(x => !x.isReadOnly && x.Selected).length;\r\n item.TriesPerformedCount = historyTriesCount + newTriesCount;\r\n\r\n var completedItem = item.TriesPerformedCount >= item.MandatoryCount;\r\n\r\n if (item.MandatoryCount == 0) { //non-mandatory items are considered completed if performed at least once\r\n completedItem = item.TriesPerformedCount >= 1;\r\n }\r\n\r\n var invalidItem = false;\r\n var nonCompetentItem = false;\r\n\r\n if (item.IsGradable && item.Selected) {\r\n var gradingType = item.GradeType; //Numeric or Outcome or Competences\r\n var traineeSelectedTries = item.Tries.filter(x => x.Selected);\r\n\r\n traineeSelectedTries.forEach(function (selectedTry) {\r\n\r\n var invalidGrading = gradingType != \"Competences\" && !selectedTry.TryGrading.Grade;\r\n var invalidCompetences = gradingType == \"Competences\" && !selectedTry.TryGrading.isCompetenceValid;\r\n\r\n if (invalidGrading || invalidCompetences) {\r\n invalidItem = true;\r\n }\r\n });\r\n\r\n if (!invalidItem && gradingType == \"Outcome\" && item.MandatoryCount > 0) {\r\n // Get the grades from the tries\r\n var tries = item.Tries.map(t => t.TryGrading.Grade);\r\n var mandatoryTries = item.MandatoryCount;\r\n var competentCount = 0;\r\n var nonCompetentCount = 0;\r\n var isCompetent = false;\r\n\r\n for (var i = 0; i < tries.length; i++) {\r\n if (tries[i] === 'Pass') {\r\n competentCount++;\r\n nonCompetentCount = 0; // reset non-competent count\r\n if (competentCount >= mandatoryTries) {\r\n item.PanelClass = 'panel-border-left-green';\r\n isCompetent = true;\r\n }\r\n } else {\r\n if (tries[i] === 'Fail') {\r\n nonCompetentCount++;\r\n competentCount = 0;\r\n if (nonCompetentCount >= mandatoryTries) {\r\n item.PanelClass = 'panel-border-left-pink';\r\n nonCompetentItem = true;\r\n break; // Exit if mandatory fails are reached\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (nonCompetentItem) {\r\n item.PanelClass = 'panel-border-left-pink';\r\n } else if (isCompetent) {\r\n item.PanelClass = 'panel-border-left-green';\r\n } else {\r\n item.PanelClass = 'panel-border-left-blue';\r\n }\r\n return;\r\n }\r\n\r\n if (!invalidItem && gradingType != \"Outcome\" && traineeSelectedTries.some(t => t.TryGrading.Grade === \"Fail\")) {\r\n nonCompetentItem = true;\r\n }\r\n\r\n }\r\n\r\n if (completedItem && !nonCompetentItem) {\r\n item.PanelClass = 'panel-green panel-border-left-green ';\r\n } else if ((completedItem && nonCompetentItem)) {\r\n item.PanelClass = 'panel-border-left-pink';\r\n }\r\n else {\r\n item.PanelClass = 'panel-border-left-blue ';\r\n }\r\n\r\n if (invalidItem) {\r\n item.PanelClass = 'panel-border-left-orange ';\r\n }\r\n }\r\n\r\n function updateTraineesSyllabus(item, syllabus) {\r\n var crewIds = syllabus.TraineeIds;\r\n\r\n scope.trainees.filter(x => crewIds.includes(x.CrewId)).forEach(function (trainee) {\r\n var sessionItem = trainee.Session.Items.find(sessionItem => item.Id == sessionItem.Id);\r\n sessionItem.RepeatRequired = item.RepeatRequired;\r\n sessionItem.Selected = item.Selected;\r\n sessionItem.PhaseId = item.PhaseId;\r\n sessionItem.Tries = deepCopy(item.Tries);\r\n sessionItem.SyllabusItemId = item.Id;\r\n sessionItem.TriesPerformedCount = item.TriesPerformedCount;\r\n });\r\n\r\n updatePersonalizeRemarks(item);\r\n }\r\n\r\n function deepCopy(originalObject) {\r\n return JSON.parse(JSON.stringify(originalObject));\r\n }\r\n\r\n function addTry(item, syllabus) {\r\n var competences = deepCopy(item.Competences);\r\n\r\n var newTry = {\r\n Comments: null,\r\n ActionNo: item.Tries.length + 1,\r\n Selected: true,\r\n TryGrading: { Grade: null, Competences: competences, GradeType: item.GradeType },\r\n };\r\n\r\n item.Selected = true;\r\n item.Tries.push(newTry);\r\n setPanelStyle(item);\r\n updateTraineesSyllabus(item, syllabus)\r\n }\r\n\r\n function removeTry(item, syllabus) {\r\n item.Tries.pop();\r\n\r\n if (!item.Tries.filter(x => !x.isReadOnly).length) {\r\n item.Selected = false;\r\n }\r\n setPanelStyle(item);\r\n updateTraineesSyllabus(item, syllabus)\r\n }\r\n\r\n function updateSession() {\r\n if (isGround) {\r\n TrainingSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyId, console.log, function (e) { console.log(e) })\r\n }\r\n else {\r\n FlightSessionFactory.updateSession(scope.trainees, scope.course, courseId, date, dutyNo, dutyDay, console.log, function (e) { console.log(e) })\r\n }\r\n }\r\n\r\n // if syllabus is non-gradable instructor can add persomalized trainee remarks\r\n function addTraineeRemarksRow(syllabusItem, selectedTraineeId) {\r\n if (selectedTraineeId) {\r\n var selectedTrainee = scope.trainees.find(trainee => trainee.CrewId == selectedTraineeId);\r\n if (selectedTrainee) {\r\n scope.selectedTraineeName = selectedTrainee.Name;\r\n var newTraineeRemarks = {\r\n id: selectedTrainee.CrewId,\r\n name: selectedTrainee.Name,\r\n remarks: \"\", // Add an empty remarks field for the new trainee\r\n syllabusItemId: syllabusItem.Id\r\n };\r\n\r\n syllabusItem.selectedTrainee = newTraineeRemarks;\r\n syllabusItem.traineesPersonalizedRemarks.push(newTraineeRemarks);\r\n }\r\n }\r\n }\r\n\r\n scope.getAvailableTrainees = function (allTrainees, item) {\r\n if (!item || !item.traineesPersonalizedRemarks) {\r\n return allTrainees;\r\n }\r\n \r\n // Get the IDs of already selected trainees\r\n var selectedTraineeIds = item.traineesPersonalizedRemarks.map(remark => remark.id);\r\n \r\n // Filter out the selected trainees\r\n return allTrainees.filter(trainee => !selectedTraineeIds.includes(trainee.CrewId));\r\n };\r\n\r\n function personalizedRemarksChanged(item) {\r\n if (item.usePersonalizedRemarks) {\r\n item.showPersonalizedRemarks = true;\r\n item.Tries.forEach(function (itemTry) {\r\n itemTry.Comments = \"\"; // Clear comments when enabling personalized remarks\r\n });\r\n } else {\r\n item.showPersonalizedRemarks = false;\r\n item.usePersonalizedRemarks = false;\r\n scope.traineesPersonalizedRemarks = [];\r\n }\r\n }\r\n\r\n function updatePersonalizeRemarks(item) {\r\n if (item.traineesPersonalizedRemarks && item.traineesPersonalizedRemarks.length > 0) {\r\n item.traineesPersonalizedRemarks.forEach(function (personalizedRemark) {\r\n var trainee = scope.trainees.find(x => x.CrewId == personalizedRemark.id);\r\n if (trainee) {\r\n var sessionItem = trainee.Session.Items.find(item => item.SyllabusItemId == personalizedRemark.syllabusItemId);\r\n if (sessionItem && sessionItem.Tries.length > 0) {\r\n sessionItem.Tries[0].Comments = personalizedRemark.remarks;\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n function deleteTraineeRemarks(traineeRemarks, item) {\r\n if (item) {\r\n // Remove the trainee remarks from the array\r\n var index = item.traineesPersonalizedRemarks.findIndex(remarks => remarks.id === traineeRemarks.id);\r\n if (index !== -1) {\r\n item.traineesPersonalizedRemarks.splice(index, 1);\r\n\r\n // After deleting, sync the changes with the Session\r\n updatePersonalizeRemarks(item);\r\n\r\n // Enable the deleted trainee for the current item\r\n item.selectedTrainee = null; \r\n } else {\r\n console.error(\"Trainee remarks not found for deletion.\");\r\n }\r\n } else {\r\n console.error(\"Syllabus item not found for the trainee remarks.\");\r\n }\r\n }\r\n\r\n function isAddRemarksButtonDisabled(item) {\r\n return !scope.getAvailableTrainees(scope.trainees, item).length ;\r\n };\r\n\r\n function traineeValueChanged(selectedTrainee) {\r\n if(selectedTrainee) {\r\n scope.hasSelectedTrainee = true;\r\n } else {\r\n scope.hasSelectedTrainee = false;\r\n }\r\n }\r\n }\r\n return {\r\n restrict: 'E',\r\n terminal: false,\r\n templateUrl: 'views/Training/syllabus.tpl.html',\r\n scope: false,\r\n link: link\r\n }\r\n }\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\n a3_cabin_reports.controller('TraineeSignatureModalCtrl', TraineeSignatureModalCtrl)\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name TraineeSignatureModalCtrl\r\n * @description \r\n * Shows Show Signature \r\n * @ngInject\r\n */\r\n\r\n function TraineeSignatureModalCtrl($scope, $timeout, $uibModalInstance, trainee, TrainingSessionFactory, signatureSuccess){\r\n $scope.close = close;\r\n $scope.confirmReset = confirmReset;\r\n $scope.traineeSign = traineeSign;\r\n $scope.continue = continueWarning;\r\n $scope.confirmation = false;\r\n\r\n initialiazeTrainee(trainee);\r\n function initialiazeTrainee(trainee){\r\n var signatureTrainee = deepCopy(trainee);\r\n\r\n signatureTrainee.Session.Authorized = trainee.Session.Authorized ? trainee.Session.Authorized : false;\r\n signatureTrainee.errorMessage = \"\";\r\n signatureTrainee.successMessage = \"\";\r\n signatureTrainee.responseText = null;\r\n signatureTrainee.responseHasErrors = null;\r\n signatureTrainee.success = false;\r\n signatureTrainee.isLoading = false;\r\n signatureTrainee.password = \"\";\r\n signatureTrainee.username = trainee.AimsId;\r\n signatureTrainee.PositionCode = trainee.position ? trainee.position : trainee.PositionCode;\r\n\r\n $scope.signatureTrainee = signatureTrainee;\r\n }\r\n\r\n function deepCopy(originalObject) {\r\n return JSON.parse(JSON.stringify(originalObject));\r\n }\r\n\r\n function traineeSign(signatureTrainee){\r\n\r\n if(!signatureTrainee.password || !signatureTrainee.username){\r\n signatureTrainee.errorMessage = \"Signature is required. Please enter your username and password.\";\r\n }\r\n else{\r\n signatureTrainee.isLoading = true;\r\n //Individually authorize trainee\r\n var credentials =\r\n {\r\n CrewId : signatureTrainee.CrewId,\r\n Password : signatureTrainee.password,\r\n Username : signatureTrainee.username,\r\n PositionCode : signatureTrainee.PositionCode\r\n };\r\n\r\n if($scope.isOffline){\r\n $timeout(function () {\r\n signatureTrainee.isLoading = false;\r\n }, 100);\r\n signatureTrainee.errorMessage = \"Online mode is required in order to sign. Please connect to the internet and try again.\";\r\n }\r\n else{\r\n TrainingSessionFactory.authorizeTrainee(credentials, function (responseData) {\r\n signatureTrainee.isLoading = false;\r\n signatureTrainee.success = true;\r\n\r\n signatureTrainee.Session.Authorized = true;\r\n trainee.Session.Authorized = true;\r\n\r\n signatureSuccess();\r\n\r\n \r\n }).catch(function(data){\r\n signatureTrainee.isLoading = false;\r\n if(data.data && data.data.errorMessage){\r\n signatureTrainee.errorMessage = data.data.errorMessage;\r\n }\r\n else{\r\n signatureTrainee.errorMessage = \"An error occured during your authentication\";\r\n }\r\n });\r\n }\r\n }\r\n // clear credentials\r\n trainee.username = \"\";\r\n trainee.password = \"\";\r\n }\r\n\r\n /**\r\n * Close the modal\r\n */\r\n function close(){\r\n $uibModalInstance.close(false);\r\n }\r\n\r\n /**\r\n * Confirm\r\n */\r\n function confirmReset(){\r\n $uibModalInstance.close(true);\r\n }\r\n\r\n function continueWarning(){\r\n $scope.confirmation = true;\r\n }\r\n }\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('TrainingSessionFactory', TrainingSessionFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name TrainingSessionFactory\r\n * @description \r\n * Add, Update, Delete and Get Training Courses.\r\n * @ngInject\r\n */\r\n function TrainingSessionFactory(IndexedDBService, CourseFactory, $http, apiUrl, GroundDutyFactory, $filter) {\r\n\r\n /**\r\n * Initialize Session\r\n * @memberof TrainingSessionFactory\r\n */\r\n function Session() {\r\n this.Id = null;\r\n }\r\n\r\n var objType = 'TrainingSessions';\r\n var objCallback = Session;\r\n\r\n var service = {\r\n getAll: getAll,\r\n getSession: getSession,\r\n setSession: setSession,\r\n updateSession: updateSession,\r\n getSessionTrainees: getSessionTrainees,\r\n submitSession: submitSession,\r\n remove: remove,\r\n authorizeTrainee: authorizeTrainee,\r\n getDutySessions: getDutySessions,\r\n applyTraineeInfoToSession: applyTraineeInfoToSession,\r\n releaseSession: releaseSession,\r\n createFlatHistorySullabusItem: createFlatHistorySullabusItem\r\n };\r\n\r\n\r\n /**\r\n * Get all ground training sessions\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\r\n function getAll(callback) {\r\n IndexedDBService.getAll(objType).then(function (results) {\r\n callback(results);\r\n });\r\n };\r\n\r\n /**\r\n * Get session By day and courseId\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\r\n function getSession(courseId, day, dutyId, afterRefresh, callback, errorCallback) {\r\n IndexedDBService.getById(objType, [day, courseId, dutyId]).then(function (session) {\r\n CourseFactory.getCourseFromStorage(courseId, function (course) {\r\n if (course && !course.HasLimitedInfo && course.CrewCoursePhases && course.CourseTrainees) {\r\n mergeCourseWithSession(course, session, dutyId, afterRefresh);\r\n }\r\n callback(course);\r\n }, errorCallback);\r\n })\r\n .catch(errorCallback);\r\n }\r\n\r\n function getDutySessions(day, dutyId, callback) {\r\n IndexedDBService.getAll(objType).then(function (results) {\r\n results = results.filter(x => x.day == day && x.dutyId == dutyId)\r\n callback(results);\r\n });\r\n }\r\n\r\n /**\r\n * Remove session By day,dutyID (Optional) and courseId\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\r\n function remove(courseId, day, dutyId, callback, errorCallback) {\r\n IndexedDBService.remove(objType, [day, courseId, dutyId])\r\n .then(callback)\r\n .catch(errorCallback);\r\n };\r\n\r\n /**\r\n * Get session Trainees By day and courseId\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\r\n function getSessionTrainees(courseId, day, dutyId, callback, errorCallback) {\r\n IndexedDBService.getById(objType, [day, courseId, dutyId]).then(function (session) {\r\n var trainees = session && session.trainees ? session.trainees : [];\r\n callback(trainees);\r\n })\r\n .catch(errorCallback);\r\n };\r\n\r\n /**\r\n * Set session\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\r\n function setSession(session, callback, errorCallback) {\r\n IndexedDBService.getById(objType, [session.day, session.courseId, session.dutyId]).then(function (result) {\r\n if (result) {\r\n saveSessionToStorage(session).then(callback).catch(errorCallback);;\r\n } else {\r\n addSessionToStorage(session).then(callback).catch(errorCallback);\r\n }\r\n }).catch(errorCallback);\r\n };\r\n\r\n /**\r\n * Set session\r\n * @memberof TrainingSessionFactory\r\n * @param {function} callback \r\n */\r\n function updateSession(trainees, session, courseId, day, dutyId, callback, errorCallback) {\r\n IndexedDBService.getById(objType, [day, courseId, dutyId])\r\n .then(function (localSession) {\r\n var isNewSession = false;\r\n if (!localSession) {\r\n localSession = { courseId: courseId, day: day, dutyId: dutyId, trainees: [] }\r\n isNewSession = true;\r\n } else {\r\n localSession.trainees = [];\r\n }\r\n\r\n if (session) {\r\n localSession.Media = session.Media;\r\n localSession.ReleasedPhase = session.ReleasedPhase;\r\n localSession.TraineeEligibilty = session.TraineeEligibilty;\r\n }\r\n\r\n trainees.forEach(function (trainee) {\r\n localSession.trainees.push(trainee);\r\n });\r\n\r\n if (isNewSession) {\r\n addSessionToStorage(localSession).then(callback).catch(errorCallback);\r\n } else {\r\n saveSessionToStorage(localSession).then(callback).catch(errorCallback);\r\n }\r\n }).catch(errorCallback);\r\n }\r\n\r\n function mergeCourseWithSession(course, session, dutyId, afterRefresh) {\r\n course.HasLimitedSession = session == undefined;\r\n \r\n var hasPreviousSessions = mergeSyllabusWithHistory(course.CourseTrainees, course.CrewCoursePhases);\r\n filterTraineesByEligibility(dutyId, course, session, afterRefresh);\r\n\r\n course.CrewCoursePhases.forEach(function (phase) {\r\n calculatePhaseStatus(phase, course, session);\r\n });\r\n course.selectedPhase = getSelectedPhase(course);\r\n\r\n \r\n // Calculate eligible trainees phase status\r\n course.CourseTrainees.forEach(function (trainee) {\r\n var traineePhase = trainee.Phases.find(x => x.PhaseId == course.selectedPhase.PhaseId);\r\n if (traineePhase) {\r\n trainee.ActivePhaseStatus = traineePhase.PhaseStatus;\r\n } else {\r\n trainee.ActivePhaseStatus = \"Pending\";\r\n }\r\n trainee.Selectable = trainee.ActivePhaseStatus == \"InProgress\";\r\n });\r\n\r\n \r\n //Filter By Role: Filter out trainees that have a flight crew role\r\n if(course.selectedPhase.FilterByRole){\r\n course.CourseTrainees.filter(x => x.Selectable && x.PositionCode!='SA' && x.PositionCode!='FA').forEach(function(flightCrewTrainee){\r\n flightCrewTrainee.EligibilityStatus = false;\r\n flightCrewTrainee.EligibilityDesc = \"InvalidRole\";\r\n course.NonEligibleTrainees.push(flightCrewTrainee);\r\n });\r\n }\r\n \r\n // Non InProgress trainees will be marked as NonEligible (remove further ahead trainees on multiple InProgress phases)\r\n course.CourseTrainees.filter(x => !x.Selectable).forEach(function (invalidPhaseTrainee) {\r\n invalidPhaseTrainee.EligibilityStatus = false;\r\n invalidPhaseTrainee.EligibilityDesc = \"AlreadySubmitted\";\r\n course.NonEligibleTrainees.push(invalidPhaseTrainee);\r\n });\r\n\r\n course.CourseTrainees = course.CourseTrainees.filter(x => x.EligibilityStatus);\r\n\r\n // Get trainee sessions\r\n course.CourseTrainees.forEach(function (trainee) {\r\n var sessionTrainee = session ? session.trainees.find(x => x.CrewId == trainee.CrewId) : null;\r\n if (sessionTrainee) {\r\n trainee.Session = sessionTrainee.Session;\r\n sessionTrainee.Session.AdditionalTrainingStatus = sessionTrainee.AdditionalTrainingStatus;\r\n } else {\r\n trainee.Session = {\r\n Released: course.selectedPhase.ModuleType == \"Training\" ? false : true,\r\n CrewId: trainee.CrewId,\r\n Items: [],\r\n Absent: false,\r\n DayGrading: {\r\n Comments: null,\r\n Grade: null,\r\n Competences: []\r\n },\r\n ReleaseGrading: {\r\n Comments: null,\r\n Grade: null,\r\n Competences: []\r\n }, \r\n NeedsAdditionalTraining: false,\r\n AdditionalTrainingRemarks: null,\r\n CompleteAdditionalTraining: false,\r\n NeedsAdditionalTraining: false,\r\n AdditionalTrainingStatus: null\r\n }\r\n }\r\n });\r\n\r\n /* Set default values for release option\r\n Training Modules: 'No' release as default\r\n Check Module: 'Yes' release as default\r\n */\r\n course.ReleasedPhase = course.selectedPhase.ModuleType == \"Training\" ? false : true;\r\n\r\n if (session) {\r\n course.Media = session.Media;\r\n course.ReleasedPhase = session.ReleasedPhase;\r\n course.TraineeEligibilty = session.TraineeEligibilty;\r\n }\r\n }\r\n\r\n function getSelectedPhase(course) {\r\n var hasSelectedPhase = false;\r\n var phases = course.CrewCoursePhases;\r\n\r\n phases.forEach(function (phase, index, array) {\r\n phase.isFirst = index == 0;\r\n phase.isLast = (index + 1 == array.length);\r\n // Select the first InProgress & selected phase\r\n if (!hasSelectedPhase && phase.Status == \"InProgress\" && phase.isSelected) {\r\n phase.Selected = true;\r\n hasSelectedPhase = true;\r\n }\r\n });\r\n \r\n // Select the first InProgress phase\r\n if (!hasSelectedPhase && phases.some(x => x.Status == \"InProgress\")) {\r\n phases.find(x => x.Status == \"InProgress\").Selected = true;\r\n hasSelectedPhase = true;\r\n }\r\n\r\n if (!hasSelectedPhase) {\r\n phases.find(x => x.isFirst).Selected = true;\r\n }\r\n\r\n var selectedPhase = phases.find(x => x.Selected);\r\n return selectedPhase;\r\n }\r\n\r\n\r\n function filterTraineesByEligibility(dutyId, course, session, afterRefresh) {\r\n var groundDuty = GroundDutyFactory.getGroundDutyFromStorage(dutyId);\r\n // Trainee Eligiblity cases\r\n // 1. After refresh - Save newly fetched eligibility in session\r\n // 2. No refresh & Session exists - Get last fetched eligibility from session\r\n // 3. No refresh & No session exists - Rely on previously fetched eligibility (different duty - same course)\r\n\r\n var traineeEligibility = course.TraineeEligibilty;\r\n if(!afterRefresh && session && session.TraineeEligibilty){ \r\n traineeEligibility = session.TraineeEligibilty;\r\n }\r\n if(session) session.TraineeEligibilty = traineeEligibility; //update session eligibility\r\n\r\n\r\n // Get ground duty trainees without any training records\r\n var trainees = getGroundCourseTrainees(groundDuty, course.Id)\r\n var inactiveTrainees = trainees.filter(x => !course.CourseTrainees.some(z => z.CrewId == x.CrewId));\r\n\r\n //Exclude Non valid trainees\r\n var eligibleTraineeIds = Object.keys(traineeEligibility).filter(x => traineeEligibility[x] == \"NotStarted\" || traineeEligibility[x] == \"ValidPhase\" || traineeEligibility[x] == \"FailedCertificate\").map(Number);\r\n var eligibleTrainees = inactiveTrainees.filter(x => eligibleTraineeIds.includes(x.CrewId));\r\n eligibleTrainees.forEach(function (trainee) { trainee.EligibilityStatus = true });\r\n createNewPhaseTrainees(groundDuty, course, eligibleTrainees);\r\n\r\n // Merge eligibleTrainees (inactive) with CourseTrainees (eligible & active)\r\n course.CourseTrainees.forEach(function (trainee) { trainee.EligibilityStatus = true });\r\n course.CourseTrainees.push(...eligibleTrainees);\r\n\r\n // Non eligible trainees\r\n var nonEligibleTrainees = inactiveTrainees.filter(x => !eligibleTraineeIds.includes(x.CrewId));\r\n course.NonEligibleTrainees = nonEligibleTrainees;\r\n\r\n nonEligibleTrainees.forEach(function (trainee) {\r\n trainee.EligibilityStatus = false;\r\n trainee.EligibilityDesc = traineeEligibility[trainee.CrewId];\r\n });\r\n\r\n // Result:\r\n // CourseTrainees = eligible trainees (active or new)\r\n // Non EligibleTrainees\r\n }\r\n\r\n /**\r\n * Create first phase foreach trainee\r\n * @param {object} groundDuty \r\n * @param {object} course \r\n * @param {array} trainees Eligible trainees that haven't yet started training\r\n */\r\n function createNewPhaseTrainees(groundDuty, course, trainees) {\r\n //Match GroundDutyNos with PhaseDutyNos\r\n var crewCoursePhaseDutyNos = [];\r\n var groundDutyTraineeDutyNos = [];\r\n course.CrewCoursePhases.forEach(function(coursePhase){\r\n crewCoursePhaseDutyNos = crewCoursePhaseDutyNos.concat(coursePhase.GroundDutyCodes);\r\n });\r\n\r\n groundDuty.Trainees.forEach(function(relatedDuty){\r\n groundDutyTraineeDutyNos.push(relatedDuty.GroundDutyNo.toString());\r\n });\r\n \r\n var relatedDutyNos = crewCoursePhaseDutyNos.filter(x => groundDutyTraineeDutyNos.includes(x));\r\n var relatedPhases = course.CrewCoursePhases.filter(x => x.GroundDutyCodes.some(gdc => relatedDutyNos.includes(gdc)));\r\n\r\n //From related phases, select first in order\r\n relatedPhases = $filter('orderBy')(relatedPhases, 'OrderNo');\r\n var firstPhase = relatedPhases[0];\r\n\r\n trainees.forEach(function (trainee) {\r\n trainee.Phases = [{\r\n PhaseId: firstPhase.PhaseId,\r\n PhaseStatus: \"InProgress\",\r\n RepeatRequestedItems: [],\r\n isSelected: true //selectedPhase\r\n }];\r\n });\r\n }\r\n\r\n function getGroundCourseTrainees(groundDuty, courseId) {\r\n var trainees = [];\r\n groundDuty.RelatedGroundDuties.filter(x => x.Courses && x.Courses.map(function (course) { return course.CourseId }).includes(courseId)).forEach(function (item) {\r\n item.CrewMembers.forEach(function (crewMember) {\r\n var trainee = { AimsId: crewMember.AIMS_ID, CrewId: crewMember.Id, Name: crewMember.Name, PositionCode: crewMember.PositionCode }\r\n trainees.push(trainee);\r\n })\r\n })\r\n return trainees;\r\n }\r\n\r\n function calculatePhaseStatus(phase, course) {\r\n course.CourseTrainees.forEach(function (trainee) {\r\n var traineePhase = trainee.Phases.find(x => x.PhaseId == phase.PhaseId);\r\n if (traineePhase && traineePhase.PhaseStatus == \"InProgress\") {\r\n phase.Status = \"InProgress\";\r\n } else if (!traineePhase && phase.Status != \"InProgress\") {\r\n phase.Status = \"Pending\";\r\n } else if (traineePhase && traineePhase.PhaseStatus == \"Completed\" && phase.Status != \"InProgress\") {\r\n phase.Status = \"Completed\";\r\n }\r\n //Selected phase, If at least one trainee has it selected\r\n if(traineePhase && !phase.isSelected){\r\n phase.isSelected = traineePhase.isSelected;\r\n }\r\n });\r\n }\r\n\r\n function mergeSyllabusWithHistory(trainees, phases) {\r\n var flatSullabusItems = [];\r\n trainees.forEach(function (trainee) {\r\n trainee.Phases.forEach(function (phase) {\r\n phase.Sessions.forEach(function (session) {\r\n session.Items.forEach(function (item) {\r\n var flatItem = createFlatHistorySullabusItem(trainee, phase, session, item);\r\n flatSullabusItems.push(flatItem);\r\n });\r\n });\r\n });\r\n });\r\n\r\n\r\n phases.filter(x => x.Syllabus).forEach(function (phase, index, array) {\r\n phase.Syllabus.SyllabusItems.forEach(function (syllabusItem) {\r\n syllabusItem.History = flatSullabusItems.filter(item => item.ItemId == syllabusItem.Id);\r\n })\r\n });\r\n var hasPreviousSessions = flatSullabusItems.length > 0;\r\n\r\n return hasPreviousSessions;\r\n }\r\n\r\n function createFlatHistorySullabusItem(trainee, phase, session, item) {\r\n var flatItem = {\r\n CrewId: trainee.CrewId,\r\n PhaseId: phase.PhaseId,\r\n SessionId: session.SessionId,\r\n SessionComments: session.SessionComments,\r\n SubmissionDate: item.SubmissionDate,\r\n RepeatRequired: item.RepeatRequired,\r\n Tries: item.Tries,\r\n ItemId: item.SyllabusItemId,\r\n Grade: session.Grade,\r\n GradeType: session.GradeType,\r\n InstructorName: session.InstructorName,\r\n InstructorAimsId: session.InstructorAimsId\r\n };\r\n return flatItem;\r\n }\r\n\r\n /**\r\n * Add Session to Storage\r\n * @memberof TrainingSessionFactory\r\n * @param {object} Session\r\n */\r\n function addSessionToStorage(session) {\r\n return IndexedDBService.add(objType, session);\r\n };\r\n\r\n /**\r\n * Update Session to Storage\r\n * @memberof TrainingSessionFactory\r\n * @param {object} Session\r\n */\r\n function saveSessionToStorage(session) {\r\n return IndexedDBService.put(objType, session);\r\n };\r\n\r\n function submitSession(submittedSession, callback) {\r\n var traingingApiURL = apiUrl + '/Training/SubmitTraining';\r\n return $http.post(traingingApiURL, submittedSession, { 'Content-Type': 'application/json' })\r\n .then(callback);\r\n }\r\n\r\n /**\r\n * Authorize Trainee for submission\r\n * @param {string} credentials Trainee's password, username, crewId, position\r\n * @param {function} callback \r\n * @param {function} errorCallback \r\n */\r\n function authorizeTrainee(credentials, callback, errorCallback) {\r\n return $http.post(apiUrl + '/Training/AuthorizeTrainee', credentials, { 'Content-Type': 'application/json' })\r\n .then(callback)\r\n .catch(errorCallback);\r\n }\r\n\r\n function applyTraineeInfoToSession(course, courseId, day, dutyId, callback, errorCallback){\r\n IndexedDBService.getById(objType, [day, courseId, dutyId])\r\n .then(function (localSession) {\r\n var isNewSession = false;\r\n if (!localSession) {\r\n localSession = { \r\n courseId: courseId, \r\n day: day, \r\n dutyId: dutyId, \r\n trainees: [],\r\n TraineeEligibilty : course.TraineeEligibilty,\r\n CourseTrainees : course.CourseTrainees\r\n };\r\n isNewSession = true;\r\n } \r\n else{\r\n localSession.TraineeEligibilty = course.TraineeEligibilty;\r\n localSession.CourseTrainees = course.CourseTrainees;\r\n }\r\n\r\n if (isNewSession) {\r\n addSessionToStorage(localSession).then(callback).catch(errorCallback);\r\n } else {\r\n saveSessionToStorage(localSession).then(callback).catch(errorCallback);\r\n }\r\n }).catch(errorCallback);\r\n }\r\n\r\n function releaseSession(submittedSessions, callback, errorCallback) {\r\n var traingingApiURL = apiUrl + '/Training/ReleaseSession';\r\n return $http.post(traingingApiURL, submittedSessions, { 'Content-Type': 'application/json' })\r\n .then(callback)\r\n .catch(errorCallback);\r\n }\r\n return service;\r\n }\r\n})();","(function () {\r\n// Warning!!! This an auto generated file. Any Changes will be lost. If u want to add or edit go to config.json \r\n\r\na3_cabin_reports.constant(\"version\", \"appVersion_20170424105730\");\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('DebugCtrl',DebugCtrl);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name DebugCtrl\r\n * @description \r\n * Manage Debug view\r\n * @ngInject\r\n */ \r\nfunction DebugCtrl($location, $scope, UserFactory, DebugFactory, localStorageMD5Service) {\r\n\r\n\t\t$scope.isSecure = UserFactory.isSecure();\r\n\t\t$scope.adminkey = \"\";\r\n\t\t$scope.authorized = false;\r\n\r\n\r\n\t\t// show logged user info\r\n\t\tvar user = UserFactory.getUser();\r\n\t\t$scope.logged_user_info = \"-user has not logged in-\";\r\n\t\tif (user)\r\n\t\t\t$scope.logged_user_info = user.aimsId + ' - ' + user.name;\r\n\r\n\t\t$scope.storedValues = [];\r\n\t\t$scope.addKeyName = null;\r\n\t\t\r\n $scope.checkAuthorized = checkAuthorized;\r\n $scope.refreshStoredValues = refreshStoredValues;\r\n\r\n\r\n\t\t$scope.add = add;\r\n\r\n\t\t$scope.update = update; \r\n\r\n\t\t$scope.delete = deleteFromStorage;\r\n \r\n\t\t$scope.exit = exit;\r\n \r\n $scope.updateAll = updateAll;\r\n \r\n \r\n /**\r\n * Update all the local storage \r\n * @memberof DebugCtrl\r\n */\r\n function updateAll()\r\n {\r\n try {\r\n var items = JSON.parse($scope.updateAllJson); \r\n \r\n for(var i=0; i 0) {\r\n\t\t\t\t\talert('Key exists!');\r\n\t\t\t\t\treturn false;\r\n\t\t\t\t}\r\n\t\t\t\tlocalStorageMD5Service.set(key, [\"empty\"])\r\n\t\t\t\t$scope.refreshStoredValues();\r\n\t\t\t\t$scope.addKeyName = null;\r\n\t\t\t} catch (e) {\r\n\t\t\t\talert('Error: ' + e.message || e.errorMessage);\r\n\t\t\t}\r\n\t\t}\r\n \r\n /**\r\n * Update an existing local storage key\r\n * @memberof DebugCtrl\r\n * @param {object} item\r\n */\r\n function update(item) {\r\n\t\t\ttry {\r\n\t\t\t\tvar obj = null;\r\n\t\t\t\tif (item.value != '') obj = angular.fromJson(item.value);\r\n\t\t\t\tlocalStorageMD5Service.set(item.key, obj);\r\n\t\t\t\t$scope.refreshStoredValues();\r\n\t\t\t} catch (e) {\r\n\t\t\t\talert('Error: ' + e.message || e.errorMessage);\r\n\t\t\t}\r\n\t\t}\r\n \r\n /**\r\n * delete an existing local storage key\r\n * @memberof DebugCtrl\r\n * @param {object} item\r\n */\r\n function deleteFromStorage(item) {\r\n\t\t\tif (confirm('Confirm deletion of key ' + item.key)) {\r\n\t\t\t\tlocalStorageMD5Service.remove(item.key);\r\n\t\t\t\t$scope.refreshStoredValues();\r\n\t\t\t}\r\n\t\t}\r\n \r\n /**\r\n * Check if the user is authorized in order to view key values\r\n * @memberof DebugCtrl\r\n */\r\n function checkAuthorized() {\r\n\t\t\tvar verify = localStorageMD5Service.md5hash($scope.adminkey);\r\n\t\t\tDebugFactory.CheckAuthorized(verify, function(responseData){\r\n\t\t\t\tif ($scope.authorized != responseData.data.data) {\r\n\t\t\t\t\t$scope.authorized = responseData.data.data;\r\n\t\t\t\t\t$scope.refreshStoredValues();\r\n\t\t\t\t}\r\n\t\t\t}).catch(function(error){\r\n\t\t\t\t$scope.authorized = responseData.Data;\r\n\t\t\t\tconsole.error('Wrong Password', error.status, error.statusText);\r\n\t\t\t});\r\n\t\t}\r\n \r\n /**\r\n * Refresh values from localstorage\r\n * @memberof DebugCtrl\r\n */\r\n function refreshStoredValues() {\r\n\t\t\tvar values = [];\r\n\t\t\tif ($scope.authorized) {\r\n\t\t\t\tvar keys = localStorageMD5Service.keys();\r\n\t\t\t\tif (keys) {\r\n\t\t\t\t\tvar key, value, sizeActual, error;\r\n\t\t\t\t\tfor (var i = 0; i < keys.length; i++) {\r\n\t\t\t\t\t\tkey = keys[i];\r\n\t\t\t\t\t\ttry {\r\n\t\t\t\t\t\t\tvalue = localStorageMD5Service.get(key);\r\n\t\t\t\t\t\t\tvalue = angular.toJson(value);\r\n\t\t\t\t\t\t\tsizeActual = localStorageMD5Service.usedSize(key);\r\n\t\t\t\t\t\t\terror = null;\r\n\t\t\t\t\t\t} catch (e) {\r\n\t\t\t\t\t\t\terror = e.message || e.errorMessage;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tvalues.push({\r\n\t\t\t\t\t\t\tkey: key,\r\n\t\t\t\t\t\t\tvalue: value,\r\n\t\t\t\t\t\t\terror: error,\r\n\t\t\t\t\t\t\tsize: (value) ? value.length : 0,\r\n\t\t\t\t\t\t\tsizeActual: sizeActual\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t$scope.storedValues = values;\r\n\r\n\t\t}\r\n \r\n /**\r\n * Redirect to main Menu\r\n * @memberof DebugCtrl\r\n */\r\n function exit() {\r\n\t\t\t$location.path(\"/\");\r\n\t\t}\r\n\r\n\r\n\t}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n a3_cabin_reports.factory('DebugFactory', DebugFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name DebugFactory\r\n * @description \r\n * Authorize check from API ...\r\n * @ngInject\r\n */\r\n function DebugFactory(GenericService, $http, $q, apiUrl, LogService){\r\n /**\r\n * Initialize Debug\r\n * @memberof DebugFactory\r\n */\r\n var service = {\r\n CheckAuthorized: CheckAuthorized\r\n }\r\n function CheckAuthorized(value, callback){\r\n return $http.get(apiUrl + '/debug/CheckAuthorized/' + value, { 'Content-Type': 'application/json' })\r\n .then(callback);\r\n }\r\n\r\n return service;\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('ResetDeviceCtrl',ResetDeviceCtrl);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ResetDeviceCtrl\r\n * @description \r\n * Manage Reset view\r\n * @ngInject\r\n */ \r\nfunction ResetDeviceCtrl($location, $scope, DataCleanerFactory, UserFactory) {\r\n\r\n\t\t$scope.isSecure = UserFactory.isSecure();\r\n\r\n\t\t// show logged user info\r\n\t\tvar user = UserFactory.getUser();\r\n\t\t$scope.logged_user_info = \"-user has not logged in-\";\r\n\t\tif (user)\r\n\t\t\t$scope.logged_user_info = user.aimsId + ' - ' + user.name;\r\n\r\n\t\t$scope.resetDevice = resetDevice;\r\n $scope.cancelReset = cancelReset; \r\n \r\n /**\r\n * Reset Device storage\r\n * @memberof ResetDeviceCtrl\r\n */\r\n function resetDevice() {\r\n\t\t\tDataCleanerFactory.deleteAllData();\r\n\t\t\tbootbox.alert(\"Your device has been reset.\", function() {\r\n\t\t\t\t$location.path(\"/login\");\r\n\t\t\t\t$scope.$apply();\r\n\t\t\t});\r\n\t\t}\r\n \r\n /**\r\n * Cancel Reset and go to main page.\r\n * @memberof ResetDeviceCtrl\r\n */\r\n function cancelReset() {\r\n\t\t\t$location.path(\"/\");\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();","(function () {\r\n 'use strict';\r\n\r\n a3_cabin_reports.factory('WifiAvailabilityFactory', WifiAvailabilityFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name WifiAvailabilityFactory\r\n * @description \r\n * Storage of aircraft registrations with Wi-Fi connectivity.\r\n * @ngInject\r\n */\r\n function WifiAvailabilityFactory(GenericService) {\r\n\r\n var objType = 'WifiAvailability';\r\n var objCallback = WifiAvailability;\r\n\r\n\r\n /**\r\n * Initialize the WifiAvailability\r\n * @memberof WifiAvailabilityFactory\r\n */\r\n function WifiAvailability() {\r\n this.Registrations = [];\r\n }\r\n\r\n var service = {\r\n setRegistrationsToStorage: setRegistrationsToStorage,\r\n getRegistrationsFromStorage: getRegistrationsFromStorage,\r\n };\r\n\r\n /**\r\n * Save registrations with Wi-Fi connectivity to storage\r\n * @param {array} objList A list of aircraft registrations\r\n */\r\n function setRegistrationsToStorage(objList) {\r\n if (objList != null) {\r\n var registrations = { registrations: objList};\r\n GenericService.saveOne(registrations, objType, objCallback);\r\n }\r\n }\r\n\r\n /**\r\n * Get registrations from storage\r\n */\r\n function getRegistrationsFromStorage() {\r\n return GenericService.getOne(objType, objCallback);\r\n }\r\n\r\n return service;\r\n }\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('wifiPrograms',wifiPrograms);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name wifiPrograms\r\n * @restrict EA\r\n * @description\r\n * Implementation of wifiPrograms\r\n *\r\n * Initialize the wifi programs panel needs to have flight in scope\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */ \r\nfunction wifiPrograms( ) {\r\n \r\n /**\r\n * Initialize wifiVouchers\r\n * @memberof wifiVouchers\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\r\n function link (scope, element, attrs) {\r\n // scope.textAndSurfCodes = [];\r\n // scope.streamCodes = [];\r\n }\r\n return {\r\n\t\t\trestrict: 'EA',\r\n\t\t\tterminal: true,\r\n templateUrl: 'views/WifiVouchers/wifiPrograms.tpl.html',\r\n\t\t\tscope : false,\r\n link: link \r\n }\r\n}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.directive('wifiVouchers',wifiVouchers);\r\n \r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc directive\r\n * @name wifiVouchers\r\n * @restrict EA\r\n * @description\r\n * Implementation of wifiVouchers\r\n *\r\n * Initialize the wifi vouchers panel needs to have flight in scope\r\n * @example\r\n * Usage:\r\n * \r\n * @ngInject\r\n */ \r\nfunction wifiVouchers(WifiVouchersFactory, WifiAvailabilityFactory, $timeout ) {\r\n \r\n /**\r\n * Initialize wifiVouchers\r\n * @memberof wifiVouchers\r\n * @param {service} scope the scope of this element\r\n * @param {service} element element that this direcive is assigned to\r\n * @param {service} attributes attributes of this element\r\n */\r\n function link (scope, element, attrs) { \r\n\r\n\t\tvar wifiAvailability = WifiAvailabilityFactory.getRegistrationsFromStorage();\r\n if(wifiAvailability){\r\n scope.supportsWifi = wifiAvailability.registrations.includes(scope.flight.AcTailNo);\r\n }else{\r\n scope.supportsWifi = false;\r\n }\r\n\r\n scope.retrieve = retrieve;\r\n // scope.createVoucher = createVoucher;\r\n scope.showPanel = '';\r\n scope.submitMessage = '';\r\n scope.pnrNo = null;\r\n scope.wifiVouchersCodes = [];\r\n scope.textAndSurfCodes = [];\r\n scope.streamCodes = [];\r\n scope.isFlightView = true;\r\n\r\n function retrieve(pnrNo) {\r\n if(scope.isOffline){\r\n scope.showPanel = \"offline\";\r\n }\r\n else{\r\n scope.showPanel = \"loading\"; \r\n \r\n var RequestWifiVouchers = {\r\n PNR : pnrNo,\r\n FlightId: scope.flight.FlightId,\r\n Flight: scope.paxInfo.STDLocal\r\n };\r\n WifiVouchersFactory.retrieveWifiVouchers(RequestWifiVouchers)\r\n .then(res => handleSubmitResponse(res)); \r\n }\r\n }\r\n\r\n \tfunction handleSubmitResponse(res) {\r\n\t\t\tif (res.success) {\r\n scope.notRetrieved = false;\r\n scope.textAndSurfCodes = [];\r\n scope.streamCodes = [];\r\n\t\t\t\tmanageResponseMessage(\"success\", res.message);\r\n\t\t\t\tscope.wifiVouchersCodes = res.data;\r\n\r\n\t\t\t\tscope.wifiVouchersCodes.forEach(function (code) {\r\n if(code.Type == 'Text & Surf') {\r\n scope.textAndSurfCodes.push(code.VoucherCode);\r\n }\r\n });\r\n\r\n\t\t\t\tscope.wifiVouchersCodes.forEach(function (code) {\r\n if(code.Type == 'Stream') {\r\n scope.streamCodes.push(code.VoucherCode);\r\n }\r\n });\r\n\t\t\t}\r\n\t\t\telse {\r\n\t\t\t\tmanageResponseMessage(\"failure\", res.message);\r\n\t\t\t}\r\n\t\t}\r\n\r\n /**\r\n * Manage message alerts\r\n * @param {string} panelToShow \r\n * @param {string} message \r\n */\r\n function manageResponseMessage(panelToShow, message) {\r\n scope.submitMessage = message;\r\n scope.showPanel = panelToShow;\r\n }\r\n\r\n }\r\n return {\r\n\t\t\trestrict: 'EA',\r\n\t\t\tterminal: true,\r\n templateUrl: 'views/WifiVouchers/wifiVouchers.tpl.html',\r\n\t\t\tscope : false,\r\n link: link \r\n }\r\n}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('WifiVouchersFactory', WifiVouchersFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name WifiVouchersFactory\r\n * @description \r\n * Get Wifi VouchersFactory.\r\n * @ngInject\r\n */ \r\nfunction WifiVouchersFactory($http, apiUrl) {\r\n var submitResponseObj = { success: false, message: '', data: '' }\r\n\r\n var service = {\r\n retrieveWifiVouchers: retrieveWifiVouchers,\r\n createWifiVoucher: createWifiVoucher\r\n };\r\n\r\n /**\r\n * Retrieve Wifi Vouchers\r\n * @memberof WifiVouchersFactory\r\n * @param {function} callback \r\n */\r\n function retrieveWifiVouchers(requestObj) {\r\n var objectToAdd = requestObj;\r\n return $http.post(apiUrl + '/WifiVouchers/RetrieveVouchers/', requestObj, { 'Content-Type': 'application/json' })\r\n .then(res => retrieveVouchersSuccessCallBack(res, objectToAdd))\r\n .catch(res => vouchersFailedCallBack(res)); \r\n } \r\n\r\n /**\r\n * The callback function upon successful retrieve\r\n * @param {object} res \r\n * @param {object} objectToAdd \r\n * @returns {object} submitResponseObj\r\n */\r\n function retrieveVouchersSuccessCallBack(res, objectToAdd) {\r\n submitResponseObj.success = res.data.success;\r\n if (res.data.success && objectToAdd.PNR != null) { \r\n submitResponseObj.message = \"Success! Your input has been sent\";\r\n submitResponseObj.data = res.data.data.Result;\r\n }\r\n else if (res.data.success && objectToAdd.PNR == null){\r\n submitResponseObj.message = \"You have to fill PNR No\";\r\n } \r\n else{\r\n submitResponseObj.message = res.data.errorMessage\r\n }\r\n return submitResponseObj;\r\n }\r\n\r\n /**\r\n * Create Wifi Vouchers\r\n * @memberof WifiVouchersFactory\r\n * @param {function} callback \r\n */\r\n function createWifiVoucher(requestObj) {\r\n var objectToAdd = requestObj;\r\n\r\n return $http.post(apiUrl + '/WifiVouchers/CreateVoucher/', requestObj, { 'Content-Type': 'application/json' })\r\n .then(res => createVouchersSuccessCallBack(res, objectToAdd))\r\n .catch(res => vouchersFailedCallBack(res)); \r\n }\r\n\r\n function createVouchersSuccessCallBack(res, objectToAdd) {\r\n submitResponseObj.success = res.data.success;\r\n if (res.data.success && objectToAdd.PNR != null && res.data.data.Result && res.data.data.Result.Vouchers) { \r\n submitResponseObj.message = \"Success! Your input has been sent\";\r\n submitResponseObj.data = res.data.data.Result.Vouchers;\r\n }\r\n else{\r\n submitResponseObj.message = res.data.errorMessage\r\n }\r\n return submitResponseObj;\r\n }\r\n \r\n /**\r\n * The callback function upon failure on retrieve\r\n * @returns {object} submitResponseObj\r\n */\r\n function vouchersFailedCallBack(res) {\r\n submitResponseObj.success = false;\r\n submitResponseObj.message = \"Oops! Something went wrong\"\r\n return submitResponseObj;\r\n }\r\n return service;\r\n}\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('ACSupplyFactory', ACSupplyFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name ACSupplyFactory\r\n * @description \r\n * Manage ACSupplies.\r\n * @ngInject\r\n */\r\nfunction ACSupplyFactory(GenericValuesFactory) {\r\n \r\n /**\r\n * Initialiaze ACSupply object \r\n * @memberof ACSupplyFactory\r\n */\r\n\t\tfunction ACSupply() {\r\n\t\t\tthis.Code = null;\r\n\t\t}\r\n\t\t\t\r\n\t\tvar callback=ACSupply;\r\n\t\tvar type ='acSupplies';\r\n\t\t\t\r\n\t\tvar service = {\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\ttoObjectList : toObjectList,\r\n\t\t\tgetACSuppliesFromStorage : getACSuppliesFromStorage,\r\n\t\t\tgetACSuppliesFromStorageAsStrings : getACSuppliesFromStorageAsStrings,\r\n\t\t\tsetACSuppliesToStorage : setACSuppliesToStorage\r\n\t\t}\r\n\t \r\n /**\r\n * Extend given ACSupply object \r\n * @memberof ACSupplyFactory\r\n * @param {object} obj The ACSupply object that will be extended\r\n * @returns {object} ACSupply\r\n */\r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericValuesFactory.fromObject(obj,callback);\r\n\t\t}\r\n\r\n /**\r\n * Extend given ACSupply object list\r\n * @memberof ACSupplyFactory\r\n * @param {array} objList The list of ACSupply objects that will be extended\r\n * @returns {object} ACSupplies\r\n */\r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericValuesFactory.fromObjectList(objList,callback);\r\n\t\t}\r\n\r\n /**\r\n * Get all the ACSupply's Code from given list\r\n * @memberof ACSupplyFactory\r\n * @param {array} objectList An object list\r\n * @returns {array} ACSupplies\r\n */\r\n\t\tfunction toObjectList(objList) {\r\n\t\t\treturn GenericValuesFactory.objList(objList);\r\n\t\t}\r\n\r\n /**\r\n * Get all the ACSupply objects\r\n * @memberof ACSupplyFactory\r\n * @returns {array} ACSupplies\r\n */\r\n\t\tfunction getACSuppliesFromStorage() {\r\n\t\t\treturn GenericValuesFactory.getValuesFromStorage(callback,type);\r\n\t\t}\r\n\r\n /**\r\n * Get all the ACSupply's codes from local storage\r\n * @memberof ACSupplyFactory\r\n * @returns {array} ACSupplies\r\n */\r\n\t\tfunction getACSuppliesFromStorageAsStrings() {\r\n\t\t\treturn GenericValuesFactory.getValuesFromStorageAsStrings(callback,type);\r\n\t\t}\r\n\r\n /**\r\n * Set all the ACSupplies\r\n * @memberof ACSupplyFactory\r\n * @param {array} objects A list of ACSupplies.\r\n */\r\n\t\tfunction setACSuppliesToStorage(objList) {\r\n\t\t\tGenericValuesFactory.setValuesToStorage(objList,type);\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.factory('AircraftTypeFactory', AircraftTypeFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name AircraftTypeFactory\r\n * @description \r\n * Manage Aircraft Types.\r\n * @ngInject\r\n */\r\nfunction AircraftTypeFactory(GenericValuesFactory) {\r\n\r\n /**\r\n * Initialiaze AircraftType object \r\n * @memberof AircraftTypeFactory\r\n */\r\n\t\tfunction AircraftType() {\r\n\t\t\tthis.Code = null;\r\n\t\t}\r\n\t\tvar callback=AircraftType;\r\n\t\tvar type ='aircraftTypes';\r\n\t\t\t\r\n\t\tvar service = {\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\ttoObjectList : toObjectList,\r\n\t\t\tgetAircraftTypesFromStorage : getAircraftTypesFromStorage,\r\n\t\t\tsetAircraftTypesToStorage : setAircraftTypesToStorage\r\n\t\t}\r\n\r\n /**\r\n * Extend given AircraftType object \r\n * @memberof AircraftTypeFactory\r\n * @param {object} obj The AircraftType object that will be extended\r\n * @returns {object} AircraftType\r\n */\r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericValuesFactory.fromObject(obj,callback);\r\n\t\t}\r\n\r\n /**\r\n * Extend given AircraftType object list\r\n * @memberof AircraftTypeFactory\r\n * @param {array} objList The list of AircraftType objects that will be extended\r\n * @returns {object} AircraftTypes\r\n */\r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericValuesFactory.fromObjectList(objList,callback);\r\n\t\t}\r\n\r\n /**\r\n * Extend given AircraftType object list\r\n * @memberof AircraftTypeFactory\r\n * @param {array} objList The list of AircraftType objects that will be extended\r\n * @returns {object} AircraftTypes\r\n */\r\n\t\tfunction toObjectList(objList) {\r\n\t\t\treturn GenericValuesFactory.objList(objList);\r\n\t\t}\r\n\r\n /**\r\n * Get all the AircraftType objects\r\n * @memberof AircraftTypeFactory\r\n * @returns {array} AircraftTypes\r\n */\r\n\t\tfunction getAircraftTypesFromStorage() {\r\n\t\t\treturn GenericValuesFactory.getValuesFromStorage(callback,type);\r\n\t\t}\r\n\r\n /**\r\n * Set all the AircraftTypes\r\n * @memberof AircraftTypeFactory\r\n * @param {array} objects A list of AircraftTypes.\r\n */\r\n\t\tfunction setAircraftTypesToStorage(objList) {\r\n\t\t\tGenericValuesFactory.setValuesToStorage(objList,type);\r\n\t\t}\r\n\r\n\treturn service;\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('BarTrolleyCtrl', BarTrolleyCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name BarTrolleyCtrl\r\n * @description \r\n * Manages the Bar Trolley Modal View\r\n * @ngInject\r\n */\r\nfunction BarTrolleyCtrl($scope, $uibModalInstance, ModalDialogResultFactory, BarTrolleyFactory, bart) {\r\n\r\n\t\tvar result = ModalDialogResultFactory.createNew();\r\n\r\n\t\tif (bart == null) {\r\n\t\t\tresult.Object = BarTrolleyFactory.createNew();\r\n\t\t\tresult.isInsertMode = true;\r\n\t\t} else {\r\n\t\t\tresult.Object = BarTrolleyFactory.fromObject(bart);\r\n\t\t\tresult.isInsertMode = false;\r\n\t\t}\r\n\r\n\t\t$scope.bart = result.Object;\r\n $scope.ok = ok;\r\n\t\t$scope.cancel = cancel;\r\n \r\n /**\r\n * Close modal after u check position\r\n * @memberof BarTrolleyCtrl\r\n */\r\n function ok() {\r\n\t\t\tif ((result.Object.Position == null) || (result.Object.Position == ''))\r\n\t\t\t\tresult.Object.Position = '-';\r\n\t\t\t$uibModalInstance.close(result);\r\n\t\t}\r\n\r\n /**\r\n * Close Modal\r\n * @memberof BarTrolleyCtrl\r\n */\r\n function cancel() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.factory('BarTrolleyFactory', BarTrolleyFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name BarTrolleyFactory\r\n * @description \r\n * Manage Report's BarTrolley.\r\n * @ngInject\r\n */\r\nfunction BarTrolleyFactory(GenericModalFactory) {\r\n\r\n /**\r\n * Initialiaze BarTrolley object \r\n * @memberof BarTrolleyFactory\r\n */\r\n\t\tfunction BarTrolley() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.Position = null;\r\n\t\t\tthis.SealFound = null;\r\n this.SealLeft = null;\r\n this.Label = 'Bar trolleys';\r\n this.Photos = [];\r\n this.PhotoRemarks = null;\r\n\t\t}\r\n\r\n\t\tvar service = {\r\n\t\t\tcreateNew : createNew,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tdeleteFromList : deleteFromList\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Create a new BarTrolley object \r\n * @memberof BarTrolleyFactory\r\n * @returns {object} BarTrolley\r\n */\r\n\t\tfunction createNew() {\r\n\t\t\treturn GenericModalFactory.createNew(BarTrolley)\r\n\t\t}\r\n \r\n\t \r\n /**\r\n * Extend given BarTrolley object \r\n * @memberof BarTrolleyFactory\r\n * @param {object} obj The BarTrolley object that will be extended\r\n * @returns {object} BarTrolley\r\n */\r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericModalFactory.fromObject(obj,BarTrolley)\r\n\t\t}\r\n\r\n /**\r\n * Delete BarTrolley object from given list\r\n * @memberof BarTrolleyFactory\r\n * @param {object} obj The BarTrolley object that will be deleted\r\n * @returns {array} BarTrollies\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\treturn GenericModalFactory.deleteFromList(obj, objList)\r\n\t\t}\r\n\t\t\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('CCMSFactory', CCMSFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CCMSFactory\r\n * @description \r\n * Manage CCMS.\r\n * @ngInject\r\n */\r\nfunction CCMSFactory(GenericService) {\r\n \r\n /**\r\n * Initialiaze CCMS object \r\n * @memberof CCMSFactory\r\n */\r\n\t\tfunction CCMS() {\r\n\t\t\tthis.Aircraft = null;\r\n\t\t\tthis.Positions = new Array();\r\n this.CrewComments = new Array();\r\n\t\t}\r\n\t\t\t\r\n\t\tvar objType = 'ccms';\r\n\t\tvar objCallback = CCMS; \r\n\r\n\t\tvar service = {\r\n\t\t\tgetCCMSFromStorage : getCCMSFromStorage,\r\n\t\t\tsetCCMSToStorage : setCCMSToStorage \r\n\t\t}\r\n\r\n /**\r\n * Get all the CCMS objects\r\n * @memberof CCMSFactory\r\n * @returns {array} CCMS\r\n */\r\n\t\tfunction getCCMSFromStorage() {\r\n\t\t\treturn GenericService.list(objType,objCallback);\r\n\t\t}\r\n\r\n /**\r\n * Set all the CCMS\r\n * @memberof CCMSFactory\r\n * @param {array} objects A list of CCMS.\r\n */\r\n\t\tfunction setCCMSToStorage(ccms) {\r\n\t\t\tGenericService.saveAll(ccms,objType,objCallback);\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('CCMSCrewPositionCtrl', CCMSCrewPositionCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name CCMSCrewPositionCtrl\r\n * @description \r\n * Manages the CCMS Crew Position Modal View\r\n * @ngInject\r\n */\r\nfunction CCMSCrewPositionCtrl($scope, $uibModalInstance, ModalDialogResultFactory, CCMSCrewPositionFactory, crew) {\r\n\r\n\t\tvar result = ModalDialogResultFactory.createNew();\r\n\r\n\t\tif (crew == null) {\r\n\t\t\tresult.Object = CCMSCrewPositionFactory.createNew();\r\n\t\t\tresult.Object.IsManual = true;\r\n\t\t\tresult.isInsertMode = true;\r\n\t\t} else {\r\n\t\t\tresult.Object = CCMSCrewPositionFactory.fromObject(crew);\r\n\t\t\tresult.isInsertMode = false;\r\n\t\t}\r\n\r\n\t\t$scope.crew = result.Object;\r\n\r\n\t\t$scope.ok = ok;\r\n $scope.cancel = cancel;\r\n \r\n /**\r\n * Close modal after u check position\r\n * @memberof CCMSCrewPositionCtrl\r\n */\r\n function ok() {\r\n\t\t\tif ((result.Object.CrewId == null) || (result.Object.CrewId == ''))\r\n\t\t\t\tresult.Object.CrewId = '-';\r\n\t\t\t$uibModalInstance.close(result);\r\n\t\t}\r\n\r\n /**\r\n * Close Modal\r\n * @memberof CCMSCrewPositionCtrl\r\n */\r\n function cancel() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('CCMSCrewPositionFactory', CCMSCrewPositionFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name CCMSCrewPositionFactory\r\n * @description \r\n * Manage Report's CCMSCrewPositions.\r\n * @ngInject\r\n */\r\nfunction CCMSCrewPositionFactory(GenericModalFactory) {\r\n\r\n /**\r\n * Initialiaze CCMSCrewPosition object \r\n * @memberof CCMSCrewPositionFactory\r\n */\r\n\t\tfunction CCMSCrewPosition() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.CrewId = null;\r\n\t\t\tthis.Initials = null;\r\n\t\t\tthis.Name = null;\r\n\t\t\tthis.Position = null;\r\n\t\t\tthis.CCMS = null;\r\n\t\t\tthis.IsManual = false;\r\n this.CrewComments = null;\r\n this.HasCrewComments = false;\r\n this.needsAdditionalFeedback = false;\r\n this.HasAdditionalFeedbackComments = false;\r\n this.AdditionalFeedbackId = null;\r\n this.FeedbackAuthorName = null;\r\n this.Route = null;\r\n\t\t}\r\n\r\n\t\tvar service = {\r\n\t\t\tcreateNew : createNew,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tdeleteFromList : deleteFromList\r\n\t\t}\r\n \r\n /**\r\n * Create a new CCMSCrewPosition object \r\n * @memberof CCMSCrewPositionFactory\r\n * @returns {object} CCMSCrewPosition\r\n */\t\t\t \r\n\t\tfunction createNew() {\r\n\t\t\treturn GenericModalFactory.createNew(CCMSCrewPosition)\r\n\t\t}\r\n\r\n /**\r\n * Extend given CCMSCrewPosition object \r\n * @memberof CCMSCrewPositionFactory\r\n * @param {object} obj The CCMSCrewPosition object that will be extended\r\n * @returns {object} CCMSCrewPosition\r\n */ \r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericModalFactory.fromObject(obj,CCMSCrewPosition)\r\n\t\t}\r\n\r\n /**\r\n * Delete CCMSCrewPosition object from given list\r\n * @memberof CCMSCrewPositionFactory\r\n * @param {object} obj The CCMSCrewPosition object that will be deleted\r\n * @returns {array} CCMSCrewPositions\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\treturn GenericModalFactory.deleteFromList(obj, objList)\r\n\t\t}\r\n\t\t\r\n /**\r\n * Extend given CCMSCrewPosition object List \r\n * @memberof CCMSCrewPositionFactory\r\n * @param {object} obj The CCMSCrewPosition object that will be extended\r\n * @returns {array} CCMSCrewPositions\r\n */ \r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericModalFactory.fromObjectList(objList,CCMSCrewPosition)\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('FirstAidKitCtrl', FirstAidKitCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FirstAidKitCtrl\r\n * @description \r\n * Manages the First Aid Kit Modal View\r\n * @ngInject\r\n */\r\nfunction FirstAidKitCtrl($scope, $uibModalInstance, ModalDialogResultFactory, FirstAidKitFactory, fak,IsEMK) {\r\n\r\n\t\tvar result = ModalDialogResultFactory.createNew();\r\n console.log(\"emk \" + IsEMK);\r\n\t\tif (fak == null) {\r\n\t\t\tresult.Object = FirstAidKitFactory.createNew();\r\n result.Object.IsEMK = IsEMK;\r\n\t\t\tresult.isInsertMode = true;\r\n\t\t} else {\r\n\t\t\tresult.Object = FirstAidKitFactory.fromObject(fak);\r\n\t\t\tresult.isInsertMode = false;\r\n\t\t}\r\n\r\n\t\t$scope.fak = result.Object;\r\n $scope.IsEMK = IsEMK;\r\n \r\n\t\t$scope.ok = ok;\r\n $scope.cancel = cancel;\r\n \r\n /**\r\n * Close modal after u check position\r\n * @memberof FirstAidKitCtrl\r\n */\r\n function ok() {\r\n\t\t\tif ((result.Object.Position == null) || (result.Object.Position == ''))\r\n\t\t\t\tresult.Object.Position = '-';\r\n\t\t\t$uibModalInstance.close(result);\r\n\t\t}\r\n\r\n /**\r\n * Close Modal\r\n * @memberof FirstAidKitCtrl\r\n */\r\n function cancel() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('FirstAidKitFactory', FirstAidKitFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name FirstAidKitFactory\r\n * @description \r\n * Manage Report's FirstAidKits.\r\n * @ngInject\r\n */\r\nfunction FirstAidKitFactory(GenericModalFactory) {\r\n\r\n /**\r\n * Initialiaze FirstAidKit object \r\n * @memberof FirstAidKitFactory\r\n */\r\n\t\tfunction FirstAidKit() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.Position = null;\r\n\t\t\tthis.SealFound = null;\r\n\t\t\tthis.SealLeft = null;\r\n this.IsEMK = false;\r\n\t\t}\r\n\t\t\r\n\t\tvar service = {\r\n\t\t\tcreateNew : createNew,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tdeleteFromList : deleteFromList\r\n\t\t}\r\n\t\r\n /**\r\n * Create a new FirstAidKit object \r\n * @memberof FirstAidKitFactory\r\n * @returns {object} FirstAidKit\r\n */\t\t\t \r\n\t\tfunction createNew() {\r\n\t\t\treturn GenericModalFactory.createNew(FirstAidKit)\r\n\t\t}\r\n\r\n /**\r\n * Extend given FirstAidKit object \r\n * @memberof FirstAidKitFactory\r\n * @param {object} obj The FirstAidKit object that will be extended\r\n * @returns {object} FirstAidKit\r\n */ \r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericModalFactory.fromObject(obj,FirstAidKit)\r\n\t\t}\r\n\r\n /**\r\n * Delete FirstAidKit object from given list\r\n * @memberof FirstAidKitFactory\r\n * @param {object} obj The FirstAidKit object that will be deleted\r\n * @returns {array} FirstAidKits\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\treturn GenericModalFactory.deleteFromList(obj, objList)\r\n\t\t}\r\n \r\n /**\r\n * Extend given FirstAidKit object List \r\n * @memberof FirstAidKitFactory\r\n * @param {object} obj The FirstAidKit object that will be extended\r\n * @returns {array} FirstAidKits\r\n */ \r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericModalFactory.fromObjectList(objList,FirstAidKit)\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('FlightDetailCtrl', FlightDetailCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name FlightDetailCtrl\r\n * @description \r\n * Manages the Flight Detail Modal View\r\n * @ngInject\r\n */\r\nfunction FlightDetailCtrl($scope, $uibModalInstance, ModalDialogResultFactory, CabinReportLocalEditFactory, AircraftTypeFactory, fd) {\r\n\t\tvar result = ModalDialogResultFactory.createNew();\r\n\r\n\t\tresult.Object = CabinReportLocalEditFactory.fromObject(fd);\r\n\r\n\t\tvar reportAircraftTypes = new Array();\r\n\t\tvar allAircraftTypes = AircraftTypeFactory.getAircraftTypesFromStorage();\r\n\t\tfor (var c = 0; c < allAircraftTypes.length; c++) {\r\n\r\n\t\t\treportAircraftTypes.push(allAircraftTypes[c].Code);\r\n\t\t}\r\n\r\n\t\t$scope.aircraftTypes = reportAircraftTypes;\r\n\t\t$scope.fd = result.Object;\r\n\r\n\t\t$scope.ok = ok;\r\n\t\t$scope.cancel = cancel;\r\n \r\n \r\n /**\r\n * Close modal after u check position\r\n * @memberof FlightDetailCtrl\r\n */\r\n function ok() {\r\n\t\t\tif ((result.Object.AcType == null) || (result.Object.AcType == ''))\r\n\t\t\t\tresult.Object.AcType = '-';\r\n\t\t\t$uibModalInstance.close(result);\r\n\t\t}\r\n \r\n /**\r\n * Close Modal\r\n * @memberof FlightDetailCtrl\r\n */\r\n function cancel() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n\t}\r\n \r\n})();","(function () {\r\n\t'use strict';\r\n\r\n\ta3_cabin_reports.controller('IncompleteServicesIssueCtrl', IncompleteServicesIssueCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name IncompleteServicesIssueCtrl\r\n * @description \r\n * Manages the Special Modal View\r\n * @ngInject\r\n */\r\n\tfunction IncompleteServicesIssueCtrl($scope, $uibModalInstance, ModalDialogResultFactory, IncompleteServicesIssueFactory, IncompleteServicesSourceFactory, service, fleetId) {\r\n\t\t// setup available reasons and services\r\n\t\tvar a3Reasons = IncompleteServicesSourceFactory.getA3ReasonsFromStorage();\r\n\t\tvar oaReasons = IncompleteServicesSourceFactory.getOAReasonsFromStorage();\r\n\t\tvar a3Services = IncompleteServicesSourceFactory.getA3ServicesFromStorage();\r\n\t\tvar oaServices = IncompleteServicesSourceFactory.getOAServicesFromStorage();\r\n\t\tif (!(a3Reasons instanceof Array)) a3Reasons = [];\r\n\t\tif (!(oaReasons instanceof Array)) oaReasons = [];\r\n\t\tif (!(a3Services instanceof Array)) a3Services = [];\r\n\t\tif (!(oaServices instanceof Array)) oaServices = [];\r\n\t\tif(fleetId == 1){\r\n\t\t\t$scope.availableReasons = a3Reasons;\r\n\t\t\t$scope.availableServices = a3Services;\r\n\t\t}else{\r\n\t\t\t$scope.availableReasons = oaReasons;\r\n\t\t\t$scope.availableServices = oaServices;\r\n\t\t}\r\n\t\t//Both:\r\n\t\t// $scope.availableReasons = a3Reasons.concat(oaReasons).unique();\r\n\t\t// $scope.availableServices = a3Services.concat(oaServices).unique();\r\n\r\n\t\tvar result = ModalDialogResultFactory.createNew();\r\n\r\n\t\tif (service == null) {\r\n\t\t\tresult.Object = IncompleteServicesIssueFactory.createNew();\r\n\t\t\tresult.isInsertMode = true;\r\n\t\t} else {\r\n\t\t\tresult.Object = IncompleteServicesIssueFactory.fromObject(service);\r\n\t\t\tresult.isInsertMode = false;\r\n\t\t}\r\n\r\n\t\t$scope.service = result.Object;\r\n\t\t$scope.service.ServiceClass = $scope.service.ServiceClass == null ? 'Y' : $scope.service.ServiceClass;\r\n\r\n\t\t$scope.ok = ok;\r\n\t\t$scope.cancel = cancel;\r\n\t\t$scope.clearIncompleteServiceRemarks = clearIncompleteServiceRemarks;\r\n \r\n $scope.addRows = addRows;\r\n $scope.removeRow = removeRow;\r\n \r\n function removeRow(index){\r\n $scope.service.Rows.splice(index, 1);\r\n }\r\n \r\n function addRows(){\r\n var RowSet = { From : null , To : null };\r\n $scope.service.Rows.push(RowSet);\r\n }\r\n \r\n /**\r\n * Clear Field\r\n * @memberof IncompleteServicesIssueCtrl\r\n */\r\n\t\tfunction clearField(target, fieldName) {\r\n\t\t\tif (target[fieldName] == null || target[fieldName] == '') return false;\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Please confirm that you wish to clear this field\",\r\n\t\t\t\ttitle: \"Attention\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function () { }\r\n\t\t\t\t\t},\r\n\t\t\t\t\tok: {\r\n\t\t\t\t\t\tlabel: \"Ok\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function () {\r\n\t\t\t\t\t\t\ttarget[fieldName] = null;\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\r\n /**\r\n * Clear Special Meal Issue remarks\r\n * @memberof SpecialMealIssueCtrl\r\n */\r\n\t\tfunction clearIncompleteServiceRemarks(service) {\r\n\t\t\tclearField(service, \"Remarks\");\r\n\t\t\t//sup.Remarks = null;\r\n\t\t}\r\n\r\n /**\r\n * set date and close modal\r\n * @memberof SpecialMealIssueCtrl\r\n */\r\n\t\tfunction ok() {\r\n\t\t\tvar test = $scope.service;\r\n\r\n\t\t\t$uibModalInstance.close(result);\r\n\t\t}\r\n\r\n /**\r\n * Close modal after u check position\r\n * @memberof SpecialMealIssueCtrl\r\n */\r\n\t\tfunction cancel() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n\r\n\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('IncompleteServicesIssueFactory', IncompleteServicesIssueFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name IncompleteInFlightServicesFactory\r\n * @description \r\n * Manage Incomplete In-Flight Services Reasons.\r\n * @ngInject\r\n */\r\nfunction IncompleteServicesIssueFactory(GenericModalFactory) {\r\n\r\n\t\t\r\n\t\tvar service = {\r\n createNew : createNew,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tdeleteFromList : deleteFromList\r\n };\r\n /**\r\n * Initialiaze IncompleteService object \r\n * @memberof IncompleteInFlightServicesFactory\r\n */\r\n\t\tfunction IncompleteService() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.ServiceClass = null;\r\n\t\t\tthis.Rows = [];\r\n this.ServiceType = null;\r\n this.Reason = null;\r\n this.Remarks = null;\r\n\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Create new IncompleteService object \r\n * @memberof IncompleteInFlightServicesFactory\r\n */\r\n\t\tfunction createNew() {\r\n\t\t\tvar newObj = GenericModalFactory.createNew(IncompleteService);\r\n var RowSet = { From : null , To : null };\r\n newObj.Rows.push(RowSet);\r\n \r\n return newObj;\r\n\t\t}\r\n\r\n /**\r\n * Extend given IncompleteService object \r\n * @memberof IncompleteInFlightServicesFactory\r\n * @param {object} obj The IncompleteService object that will be extended\r\n * @returns {object} IncompleteService\r\n */ \r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericModalFactory.fromObject(obj,IncompleteService)\r\n\t\t}\r\n\r\n /**\r\n * Delete IncompleteService object from given list\r\n * @memberof IncompleteInFlightServicesFactory\r\n * @param {object} obj The IncompleteService object that will be deleted\r\n * @returns {array} IncompleteServices\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\treturn GenericModalFactory.deleteFromList(obj, objList)\r\n\t\t}\r\n\t\r\n /**\r\n * Extend given IncompleteService object List \r\n * @memberof IncompleteInFlightServicesFactory\r\n * @param {object} obj The IncompleteService object that will be extended\r\n * @returns {array} IncompleteServices\r\n */ \r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericModalFactory.fromObjectList(objList,IncompleteService)\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('IncompleteServicesSourceFactory', IncompleteServicesSourceFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name IncompleteInFlightServicesFactory\r\n * @description \r\n * Manage Incomplete In-Flight Services Reasons.\r\n * @ngInject\r\n */\r\nfunction IncompleteServicesSourceFactory(localStorageMD5Service) {\r\n\r\n\t\t\r\n\t\tvar service = {\r\n setIncompleteInFlightServiceListOfValues: setIncompleteInFlightServiceListOfValues,\r\n getA3ReasonsFromStorage: getA3ReasonsFromStorage,\r\n getOAReasonsFromStorage: getOAReasonsFromStorage,\r\n getA3ServicesFromStorage: getA3ServicesFromStorage,\r\n getOAServicesFromStorage: getOAServicesFromStorage\r\n };\r\n\r\n\t\t//Get From LocalStorage\r\n /**\r\n * Get all the Incomplete In-Flight Services Reasons for A3\r\n * @memberof IncompleteInFlightServicesFactory\r\n * @returns {array} TravelValueIncompleteReasons\r\n */\r\n\t\tfunction getA3ReasonsFromStorage() {\r\n var results = [];\r\n var listOfValues = localStorageMD5Service.get('incompleteInFlightServiceListOfValues');\r\n if(listOfValues){\r\n var A3Reasons = listOfValues.filter(function (item) {\r\n return item.Fleet == \"A3\" && item.Type == \"Reason\";\r\n });\r\n results = A3Reasons.map(function (item) {\r\n return item.Value;\r\n });\r\n }\r\n\t\t\treturn (results);\r\n }\r\n /**\r\n * Get all the Incomplete In-Flight Services Reasons for OA\r\n * @memberof IncompleteInFlightServicesFactory\r\n * @returns {array} TravelValueIncompleteReasons\r\n */\r\n\t\tfunction getOAReasonsFromStorage() {\r\n var results = [];\r\n var listOfValues = localStorageMD5Service.get('incompleteInFlightServiceListOfValues');\r\n if(listOfValues){\r\n var OAReasons = listOfValues.filter(function (item) {\r\n return item.Fleet == \"OA\" && item.Type == \"Reason\";\r\n });\r\n results = OAReasons.map(function (item) {\r\n return item.Value;\r\n });\r\n }\r\n\t\t\treturn (results);\r\n }\r\n /**\r\n * Get all the Incomplete In-Flight Services Types for A3\r\n * @memberof IncompleteInFlightServicesFactory\r\n * @returns {array} TravelValueIncompleteReasons\r\n */\r\n\t\tfunction getA3ServicesFromStorage() {\r\n var results = [];\r\n var listOfValues = localStorageMD5Service.get('incompleteInFlightServiceListOfValues');\r\n if(listOfValues){\r\n var A3Services = listOfValues.filter(function (item) {\r\n return item.Fleet == \"A3\" && item.Type == \"ServiceType\";\r\n });\r\n results = A3Services.map(function (item) {\r\n return item.Value;\r\n });\r\n }\r\n\t\t\treturn (results);\r\n }\r\n /**\r\n * Get all the Incomplete In-Flight Services Types for OA\r\n * @memberof IncompleteInFlightServicesFactory\r\n * @returns {array} TravelValueIncompleteReasons\r\n */\r\n\t\tfunction getOAServicesFromStorage() {\r\n var results = [];\r\n var listOfValues = localStorageMD5Service.get('incompleteInFlightServiceListOfValues');\r\n if(listOfValues){\r\n var A3Services = listOfValues.filter(function (item) {\r\n return item.Fleet == \"OA\" && item.Type == \"ServiceType\";\r\n });\r\n results = A3Services.map(function (item) {\r\n return item.Value;\r\n });\r\n }\r\n\t\t\treturn (results);\r\n\t\t}\r\n //Set to LocalStorage\r\n /**\r\n * Set all the Incomplete In-Flight Services List Of Values \r\n * @memberof IncompleteInFlightServicesFactory\r\n * @param {array} objects A list of IncompleteInFlightServicesFactory.\r\n */\r\n function setIncompleteInFlightServiceListOfValues (data){\r\n localStorageMD5Service.set('incompleteInFlightServiceListOfValues', data);\r\n }\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('ItemPhotosCtrl', ItemPhotosCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name ItemPhotosCtrl\r\n * @description \r\n * Manages the Item Photos Modal View\r\n * @ngInject\r\n */\r\nfunction ItemPhotosCtrl($scope, $uibModalInstance, PhotoFactory, item) {\r\n\r\n\t\t$scope.item = item;\r\n\t\t$scope.quality = 0.4;\r\n $scope.width = 1024;\r\n $scope.height = 768;\r\n $scope.comment = \"Recommended for printed documents with smaller font\";\r\n\t\t$scope.sizeLimitKb = 100;\r\n\r\n\t\t$scope.isImageTooLarge = isImageTooLarge;\r\n $scope.settingsSet = settingsSet;\r\n \t\t$scope.settingsName = settingsName;\r\n \t\t$scope.settingsText = settingsText;\r\n $scope.settings = 3;\r\n $scope.settingsMinus = settingsMinus;\r\n $scope.settingsPlus = settingsPlus;\r\n $scope.settingsDefault = settingsDefault;\r\n \t$scope.imageChanged = imageChanged;\r\n $scope.imageError = imageError;\r\n $scope.rotateImageLeft = rotateImageLeft;\r\n $scope.rotateImageRight = rotateImageRight;\r\n $scope.cancel = cancel;\r\n \t$scope.ok = ok;\r\n\t\t$scope.viewPhoto = viewPhoto;\r\n\t\t$scope.deletePhoto = deletePhoto;\r\n \r\n $scope.settingsText();\r\n \r\n /**\r\n * is Image Too Large \r\n * @memberof ItemPhotosCtrl\r\n */\r\n function isImageTooLarge() {\r\n\t\t\tvar b = false;\r\n\t\t\tvar i = $scope.item;\r\n\t\t\tif (i != null && i.Photos != null && i.Photos.length > 0 && i.Photos[0].PhotoData != null) {\r\n\t\t\t\tb = (i.Photos[0].PhotoData.length > $scope.sizeLimitKb * 1024);\r\n\t\t\t}\r\n\t\t\treturn b;\r\n\t\t}\r\n\r\n /**\r\n * Set settings\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function settingsSet() {\r\n\t\t\tif ($scope.settings == 0) {\r\n\t\t\t\t$scope.width = 320;\r\n\t\t\t\t$scope.height = 240;\r\n\t\t\t\t$scope.comment = \"Not recommended\";\r\n\t\t\t} else if ($scope.settings == 1) {\r\n\t\t\t\t$scope.width = 640;\r\n\t\t\t\t$scope.height = 480;\r\n\t\t\t\t$scope.comment = \"Recommended for objects/places\";\r\n\r\n\t\t\t} else if ($scope.settings == 2) {\r\n\t\t\t\t$scope.width = 800;\r\n\t\t\t\t$scope.height = 600;\r\n\t\t\t\t$scope.comment = \"Recommended for printed documents\";\r\n\t\t\t} else if ($scope.settings == 3) {\r\n\t\t\t\t$scope.width = 1024;\r\n\t\t\t\t$scope.height = 768;\r\n\t\t\t\t$scope.comment = \"Recommended for printed documents with smaller font\";\r\n\r\n\t\t\t} else if ($scope.settings == 4) {\r\n\t\t\t\t$scope.width = 1280;\r\n\t\t\t\t$scope.height = 1024;\r\n\t\t\t\t$scope.comment = \"Recommended for handwritten documents\";\r\n\t\t\t}\r\n\t\t}\r\n\r\n /**\r\n * Show settings name\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function settingsName() {\r\n\t\t\tif ($scope.settings == 0) return 'xsmall';\r\n\t\t\telse if ($scope.settings == 1) return 'small';\r\n\t\t\telse if ($scope.settings == 2) return 'normal';\r\n\t\t\telse if ($scope.settings == 3) return 'medium';\r\n\t\t\telse if ($scope.settings == 4) return 'high';\r\n\t\t\telse return 'High' + $scope.settings;\r\n\t\t}\r\n \r\n /**\r\n * Show settings text comment\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function settingsText() {\r\n\t\t\treturn $scope.comment + \" (\" + $scope.width + 'x' + $scope.height + ' ' + $scope.quality + \")\";\r\n\t\t}\r\n \r\n /**\r\n * Lower image settings\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function settingsMinus() {\r\n\t\t\t$scope.settings--;\r\n\t\t\tif ($scope.settings < 0) $scope.settings = 0;\r\n\t\t\t$scope.settingsSet();\r\n\t\t}\r\n \r\n /**\r\n * Higher image settings\r\n * @memberof ItemPhotosCtrl\r\n */\r\n\t\tfunction settingsPlus() {\r\n\t\t\t$scope.settings++;\r\n\t\t\tif ($scope.settings > 4) $scope.settings = 4;\r\n\t\t\t$scope.settingsSet();\r\n\t\t}\r\n \r\n /**\r\n * Set default image settings\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function settingsDefault() {\r\n\t\t\t$scope.settings = 2;\r\n\t\t\t$scope.settingsSet();\r\n\t\t}\r\n\r\n /**\r\n * Change Image settings\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function imageChanged(data) {\r\n\t\t\t//console.log('told of a new image', imageResult, this.imageBrowsed, $scope.imageBrowsed);\r\n\t\t\tvar imageResult = data; //$scope.imageBrowsed;\r\n\t\t\tif (imageResult != null) {\r\n\t\t\t\titem.Photos = [];\r\n\t\t\t\tvar img = PhotoFactory.createNew();\r\n\t\t\t\timg.PhotoData = imageResult.dataURL;\r\n\t\t\t\timg.FileType = imageResult.fileType || imageResult.file.type;\r\n\t\t\t\titem.Photos.push(img);\r\n\t\t\t\t$scope.filename = null;\r\n\t\t\t}\r\n\t\t}\r\n \r\n /**\r\n * Change Image settings\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function imageError(err) {\r\n\t\t\tconsole.log('told of an error', err);\r\n\t\t}\r\n\r\n /**\r\n * Rotate Image to the Left\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function rotateImageLeft(image) {\r\n\r\n\t\t\tvar origImg = new Image();\r\n\t\t\torigImg.src = image.PhotoData;\r\n\r\n\t\t\tvar oc = document.createElement('canvas');\r\n\t\t\tvar octx = oc.getContext('2d');\r\n\t\t\toctx.mozImageSmoothingEnabled = false;\r\n\t\t\toctx.webkitImageSmoothingEnabled = false;\r\n\r\n\t\t\t// Inverse height and width as canvas size\r\n\t\t\toc.width = origImg.height;\r\n\t\t\toc.height = origImg.width;\r\n\r\n\t\t\t// Save original grid\r\n\t\t\toctx.save();\r\n\t\t\t// Set origin of canvas to center | 0,0 is now w/2 and h/2\r\n\t\t\toctx.translate(Math.floor(origImg.height / 2), Math.floor(origImg.width / 2));\r\n\t\t\t// Rotate the whole grid by X degrees\r\n\t\t\toctx.rotate((-1) * Math.PI / 2);\r\n\t\t\t// Draw the image into the rotated grid\r\n\t\t\toctx.drawImage(origImg, -Math.floor(origImg.width / 2), -Math.floor(origImg.height / 2), Math.floor(origImg.width), Math.floor(origImg.height));\r\n\t\t\t// Restore grid coordinates\r\n\t\t\toctx.restore();\r\n\r\n\t\t\timage.PhotoData = oc.toDataURL('image/jpeg', $scope.quality);\r\n\t\t}\r\n\r\n /**\r\n * Rotate Image to the Left\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function rotateImageRight(image) {\r\n\r\n\t\t\tvar origImg = new Image();\r\n\t\t\torigImg.src = image.PhotoData;\r\n\r\n\t\t\tvar oc = document.createElement('canvas');\r\n\t\t\tvar octx = oc.getContext('2d');\r\n\t\t\toctx.mozImageSmoothingEnabled = false;\r\n\t\t\toctx.webkitImageSmoothingEnabled = false;\r\n\r\n\t\t\t// Inverse height and width as canvas size\r\n\t\t\toc.width = origImg.height;\r\n\t\t\toc.height = origImg.width;\r\n\r\n\t\t\t// Save original grid\r\n\t\t\toctx.save();\r\n\t\t\t// Set origin of canvas to center | 0,0 is now w/2 and h/2\r\n\t\t\toctx.translate(Math.floor(origImg.height / 2), Math.floor(origImg.width / 2));\r\n\t\t\t// Rotate the whole grid by X degrees\r\n\t\t\toctx.rotate(Math.PI / 2);\r\n\t\t\t// Draw the image into the rotated grid\r\n\t\t\toctx.drawImage(origImg, -Math.floor(origImg.width / 2), -Math.floor(origImg.height / 2), Math.floor(origImg.width), Math.floor(origImg.height));\r\n\t\t\t// Restore grid coordinates\r\n\t\t\toctx.restore();\r\n\r\n\t\t\timage.PhotoData = oc.toDataURL(image.FileType, $scope.quality);\r\n\t\t}\r\n\r\n /**\r\n * Close Modal\r\n * @memberof BarTrolleyCtrl\r\n */\r\n function ok() {\r\n\t\t\t$uibModalInstance.close();\r\n\t\t}\r\n\r\n /**\r\n * Close Modal\r\n * @memberof BarTrolleyCtrl\r\n */\r\n function cancel() {\r\n\t\t\t$uibModalInstance.close();\r\n\t\t}\r\n\r\n /**\r\n * View photo in new window\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function viewPhoto(pho) {\r\n\t\t\twindow.open(pho.PhotoData);\r\n\t\t}\r\n \r\n /**\r\n * Delete photo\r\n * @memberof ItemPhotosCtrl\r\n */\r\n function deletePhoto(pho) {\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Are you sure you want to delete this photo?\",\r\n\t\t\t\ttitle: \"Delete record\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tno: {\r\n\t\t\t\t\t\tlabel: \"No\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function() {}\r\n\t\t\t\t\t},\r\n\t\t\t\t\tyes: {\r\n\t\t\t\t\t\tlabel: \"Yes\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function() {\r\n\t\t\t\t\t\t\tPhotoFactory.deleteFromList(pho, item.Photos);\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t}\r\n \r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.controller('MedicalIncidentCtrl', MedicalIncidentCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name MedicalIncidentCtrl\r\n * @description \r\n * Manages the Medical Incident Modal View\r\n * @ngInject\r\n */\r\nfunction MedicalIncidentCtrl($scope, $timeout, $uibModalInstance, ModalDialogResultFactory, MedicalIncidentFactory, med) {\r\n\r\n\t\t$scope.clearField = clearField;\r\n $scope.clearMedicalRemarks = clearMedicalRemarks;\r\n $scope.clearMedicalSignature = clearMedicalSignature\r\n \r\n\t\t$scope.ok = ok; \r\n $scope.cancel = cancel; \r\n \r\n var result = ModalDialogResultFactory.createNew();\r\n\r\n\t\tif (med == null) {\r\n\t\t\tresult.Object = MedicalIncidentFactory.createNew();\r\n\t\t\tresult.isInsertMode = true;\r\n\t\t} else {\r\n\t\t\tresult.Object = MedicalIncidentFactory.fromObject(med);\r\n\t\t\tresult.isInsertMode = false;\r\n\t\t}\r\n\r\n\t\t$scope.med = result.Object;\r\n \r\n $timeout(function() {\r\n\t\t\t$('.modal-medical').find('textarea').each(function(index, item) {\r\n\t\t\t\tif (item.value != '')\r\n\t\t\t\t\tautoAdjustTextarea(item);\r\n\t\t\t});\r\n\t\t}, 500);\r\n \r\n /**\r\n * Clear Field\r\n * @memberof MedicalIncidentCtrl\r\n */\r\n function clearField(target, fieldName) {\r\n\t\t\tif (target[fieldName] == null || target[fieldName] == '') return false;\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Please confirm that you wish to clear this field\",\r\n\t\t\t\ttitle: \"Attention\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function() {}\r\n\t\t\t\t\t},\r\n\t\t\t\t\tok: {\r\n\t\t\t\t\t\tlabel: \"Ok\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function() {\r\n\t\t\t\t\t\t\ttarget[fieldName] = null;\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n /**\r\n * Clear medical remarks\r\n * @memberof MedicalIncidentCtrl\r\n */\r\n\t\tfunction clearMedicalRemarks(med) {\r\n\t\t\t$scope.clearField(med, \"Symptoms\");\r\n\t\t}\r\n\r\n /**\r\n * Clear medical signature function\r\n * @memberof MedicalIncidentCtrl\r\n */\r\n\t\tfunction clearMedicalSignature(med) {\r\n\t\t\t$scope.clearField(med, \"Signature\");\r\n\t\t\t//med.Signature = null;\r\n\t\t}\r\n\r\n /**\r\n * Close modal after u check Name\r\n * @memberof MedicalIncidentCtrl\r\n */\r\n function ok() {\r\n\t\t\tif ((result.Object.Name == null) || (result.Object.Name == ''))\r\n\t\t\t\tresult.Object.Name = '-';\r\n\t\t\t$uibModalInstance.close(result);\r\n\t\t}\r\n \r\n /**\r\n * Close modal\r\n * @memberof MedicalIncidentCtrl\r\n */\r\n function cancel() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n\r\n\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('MedicalIncidentFactory', MedicalIncidentFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name MedicalIncidentFactory\r\n * @description \r\n * Manage Report's MedicalIncindents.\r\n * @ngInject\r\n */\r\nfunction MedicalIncidentFactory(GenericModalFactory) {\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name MedicalIncidentFactory\r\n * @description \r\n * Manage Report's MedicalIncindents.\r\n * @ngInject\r\n */\r\n\t\tfunction MedicalIncident() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.FAKUsed = null;\r\n\t\t\tthis.Medicine = null;\r\n\t\t\tthis.Symptoms = null;\r\n\t\t\tthis.Signature = null;\r\n\t\t\tthis.Name = null;\r\n\t\t\tthis.Phone = null;\r\n\t\t\tthis.Email = null;\r\n\t\t\tthis.DoctorInvolved = null;\r\n\t\t\tthis.DoctorName = null;\r\n\t\t\tthis.DoctorPhone = null;\r\n this.EMFAKUsed = null;\r\n\t\t}\r\n\t\r\n\t\tvar service = {\r\n\t\t\tcreateNew : createNew,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tdeleteFromList : deleteFromList\r\n\t\t}\r\n\t\t\r\n /**\r\n * Create a new MedicalIncident object \r\n * @memberof MedicalIncidentFactory\r\n * @returns {object} MedicalIncident\r\n */\t\r\n\t\tfunction createNew() {\r\n\t\t\treturn GenericModalFactory.createNew(MedicalIncident)\r\n\t\t}\r\n\r\n /**\r\n * Create a new MedicalIncident object \r\n * @memberof MedicalIncidentFactory\r\n * @returns {object} MedicalIncident\r\n */\t\r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericModalFactory.fromObject(obj,MedicalIncident)\r\n\t\t}\r\n\r\n /**\r\n * Delete MedicalIncident object from given list\r\n * @memberof MedicalIncidentFactory\r\n * @param {object} obj The MedicalIncident object that will be deleted\r\n * @returns {array} MedicalIncindents\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\treturn GenericModalFactory.deleteFromList(obj, objList)\r\n\t\t}\r\n \r\n /**\r\n * Extend given MedicalIncident object List \r\n * @memberof MedicalIncidentFactory\r\n * @param {object} obj The MedicalIncident object that will be extended\r\n * @returns {array} MedicalIncindents\r\n */ \r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericModalFactory.fromObjectList(objList,MedicalIncident)\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('OpenReportDialogCtrl', OpenReportDialogCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name OpenReportDialogCtrl\r\n * @description \r\n * Manages the open report modal functionality \r\n * @ngInject\r\n */\r\nfunction OpenReportDialogCtrl($scope, $uibModalInstance, $location, apiUrl, UserFactory, FlightFactory, CabinReportLocalEditFactory, flightId) {\r\n\r\n\t\tvar user = UserFactory.getUser();\r\n\t\tvar allServerReports = [];\r\n\t\tvar flight = FlightFactory.getFlightFromStorage(flightId);\r\n\r\n\t\tif (flight == null)\r\n\t\t\treturn;\r\n\r\n\t\t// load the reports\r\n\t\tvar serverReportForThisUser = flight.getServerCabinReportForUser(user.aimsId);\r\n\t\tvar serverReportsByAnotherUser = flight.getServerCabinReportsByAnotherUser(user.aimsId);\r\n\t\tvar localReport = CabinReportLocalEditFactory.getCabinReportLocalEditForFlight(flightId);\r\n\r\n\t\t// the user can create a new report only if there is not an existing one and\r\n\t\t// there is not a server report by him\r\n\t\tif ((localReport != null) || (serverReportForThisUser != null))\r\n\t\t\t$scope.canCreateNewLocalReport = false;\r\n\t\telse\r\n\t\t\t$scope.canCreateNewLocalReport = true;\r\n\r\n\t\tif (serverReportForThisUser != null) {\r\n\t\t\tserverReportForThisUser.IsSameUser = \" (YOU)\";\r\n\t\t\tallServerReports.push(serverReportForThisUser);\r\n\t\t}\r\n\r\n\t\tfor (var i = 0; i < serverReportsByAnotherUser.length; i++)\r\n\t\t\tallServerReports.push(serverReportsByAnotherUser[i]);\r\n\r\n\t\t$scope.localReport = localReport;\r\n\t\t$scope.serverReports = allServerReports;\r\n\r\n\t\t$scope.cancel = cancel;\r\n $scope.createNewLocalReport = createNewLocalReport;\r\n $scope.openLocalReport = openLocalReport;\r\n $scope.openServerReport = openServerReport;\r\n\r\n /**\r\n * Close Modal\r\n * @memberof OpenReportDialogCtrl\r\n */\r\n function cancel() {\r\n\t\t\t$uibModalInstance.dismiss('');\r\n\t\t}\r\n \r\n /**\r\n * Create new report and close modal\r\n * @memberof OpenReportDialogCtrl\r\n */\r\n function createNewLocalReport() {\r\n\t\t\t$location.path(\"report/new:\" + -1 + \"/\" + flightId);\r\n\t\t\t$uibModalInstance.dismiss('');\r\n\t\t}\r\n \r\n /**\r\n * Open Local Report\r\n * @memberof OpenReportDialogCtrl\r\n * @param {object} report\r\n */\r\n function openLocalReport(report) {\r\n\t\t\t$location.path(\"report/\" + report.ReportGuid);\r\n\t\t\t$uibModalInstance.dismiss('');\r\n\t\t}\r\n\r\n /**\r\n * Open Server stored Report\r\n * @memberof OpenReportDialogCtrl\r\n * @param {object} report\r\n */\r\n function openServerReport(report) {\r\n\t\t\t// get user token and send it as a parameter on the call\r\n\t\t\tvar token = '';\r\n\t\t\tif (user != null) {\r\n\t\t\t\ttoken = user.token;\r\n\t\t\t\ttoken = encodeURIComponent(token);\r\n\r\n\t\t\t\t$location.path(\"reportsHistory/\" + report.ReportId + \"/\" + flightId+\"/Cabin\");\r\n\r\n\t\t\t}\r\n\t\t\t$uibModalInstance.dismiss('');\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.factory('PhotoFactory', PhotoFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name PhotoFactory\r\n * @description \r\n * Manage Report's Photos.\r\n * @ngInject\r\n */ \r\nfunction PhotoFactory(GenericModalFactory) {\r\n\r\n /**\r\n * Initialiaze Photo object \r\n * @memberof PhotoFactory\r\n */\r\n\t\tfunction Photo() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.Remarks = null;\r\n\t\t\tthis.RemarksShort = null;\r\n\t\t\tthis.PhotoData = null;\r\n\t\t\tthis.FileType = null;\r\n\t\t}\r\n\r\n\t\tvar service = {\r\n\t\t\tcreateNew : createNew,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tdeleteFromList : deleteFromList\r\n\t\t}\r\n\r\n /**\r\n * Create a new Photo object \r\n * @memberof PhotoFactory\r\n * @returns {object} Photo\r\n */\t\t\r\n\t\tfunction createNew() {\r\n\t\t\treturn GenericModalFactory.createNew(Photo)\r\n\t\t}\r\n\r\n /**\r\n * Extend given Photo object \r\n * @memberof PhotoFactory\r\n * @param {object} obj The Photo object that will be extended\r\n * @returns {object} Photo\r\n */ \r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericModalFactory.fromObject(obj,Photo)\r\n\t\t}\r\n\r\n /**\r\n * Delete Photo object from given list\r\n * @memberof PhotoFactory\r\n * @param {object} obj The Photo object that will be deleted\r\n * @returns {array} Photos\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\treturn GenericModalFactory.deleteFromList(obj, objList)\r\n\t\t}\r\n\t\t\r\n /**\r\n * Extend given Photo object \r\n * @memberof PhotoFactory\r\n * @param {object} obj The Photo object that will be extended\r\n * @returns {object} Photo\r\n */ \r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericModalFactory.fromObjectList(objList,Photo)\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('SeatChangeCtrl', SeatChangeCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SeatChangeCtrl\r\n * @description \r\n * Manages the seat change Modal View\r\n * @ngInject\r\n */\r\nfunction SeatChangeCtrl(changedSeat, report, paxInfo, PaxInfoFactory, $scope, $uibModalInstance) {\r\n var paxInfo = paxInfo;\r\n var allPassengers = getPassengers();\r\n $scope.allPassengers = allPassengers;\r\n $scope.clearChangedSeatsRemarks = clearChangedSeatsRemarks;\r\n\r\n\t\tvar result = {};\r\n\r\n\t\tif (changedSeat == null) {\r\n $scope.editMode = false;\r\n\t\t\tresult.Object = null;\r\n\t\t\tresult.isInsertMode = true;\r\n\t\t} else {\r\n $scope.editMode = true;\r\n result.Object = Object.assign({}, changedSeat);\r\n result.Object.check = true;\r\n\t\t\tresult.isInsertMode = false;\r\n\t\t}\r\n\r\n $scope.changedSeat = result.Object;\r\n \r\n $scope.showSeatChangeWarning = false;\r\n $scope.showSeatChangeError = false;\r\n $scope.submitSeatChange = submitSeatChange;\r\n $scope.saveSeatChange = saveSeatChange;\r\n $scope.cancel = cancel;\r\n\r\n\t\t\r\n\r\n /**\r\n * Clear Field\r\n * @memberof SeatChangeCtrl\r\n */\r\n function clearField(target, fieldName) {\r\n\t\t\tif (target[fieldName] == null || target[fieldName] == '') return false;\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Please confirm that you wish to clear this field\",\r\n\t\t\t\ttitle: \"Attention\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function() {}\r\n\t\t\t\t\t},\r\n\t\t\t\t\tok: {\r\n\t\t\t\t\t\tlabel: \"Ok\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function() {\r\n\t\t\t\t\t\t\ttarget[fieldName] = null;\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n }\r\n \r\n /**\r\n * fix any input into 000A format\r\n * @memberof SeatChangeCtrl\r\n */\r\n function formatSeatInput(){\r\n\t\t\tvar missingZeroes = 4 - $scope.changedSeat.NewSeatNo.length;\r\n\t\t\tfor (var i=0; iAttention\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function() {}\r\n\t\t\t\t\t},\r\n\t\t\t\t\tok: {\r\n\t\t\t\t\t\tlabel: \"Ok\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function() {\r\n\t\t\t\t\t\t\ttarget[fieldName] = null;\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n \r\n /**\r\n * Clear Special Meal Issue remarks\r\n * @memberof SpecialMealIssueCtrl\r\n */\r\n function clearSpecialMealIssueRemarks(smi) {\r\n\t\t\t$scope.clearField(smi, \"Remarks\");\r\n\t\t\t//sup.Remarks = null;\r\n\t\t}\r\n \r\n /**\r\n * set date and close modal\r\n * @memberof SpecialMealIssueCtrl\r\n */\r\n function ok() {\r\n\t\t\tif ((result.Object.Name == null) || (result.Object.Name == ''))\r\n\t\t\t\tresult.Object.Name = '-';\r\n\r\n\t\t\tif ($scope.smi.ReturnDate != null) {\r\n\t\t\t\tvar date = new Date($scope.smi.ReturnDate);\r\n\t\t\t\tvar offset = date.getTimezoneOffset() / 60;\r\n\t\t\t\tvar hours = date.getHours();\r\n\t\t\t\tdate.setHours(hours - offset);\r\n\r\n\t\t\t\tresult.Object.ReturnDate = date.toISOString();\r\n\t\t\t}\r\n\r\n\t\t\t$uibModalInstance.close(result);\r\n\t\t}\r\n\r\n /**\r\n * Close modal after u check position\r\n * @memberof SpecialMealIssueCtrl\r\n */\r\n function cancel() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n\r\n\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('SpecialMealIssueFactory', SpecialMealIssueFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SpecialMealIssueFactory\r\n * @description \r\n * Manage Report's SpecialMealIssues.\r\n * @ngInject\r\n */\r\nfunction SpecialMealIssueFactory(GenericModalFactory) {\r\n\r\n /**\r\n * Initialiaze SpecialMealIssue object \r\n * @memberof SpecialMealIssueFactory\r\n */\r\n\t\tfunction SpecialMealIssue() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.Name = null;\r\n\t\t\tthis.Phone = null;\r\n\t\t\tthis.Email = null;\r\n\t\t\tthis.Source = null;\r\n\t\t\tthis.MealType = null;\r\n\t\t\tthis.ReturnDate = null;\r\n\t\t\tthis.Remarks = null;\r\n\t\t}\r\n\t\t\r\n\t\tvar service = {\r\n\t\t\tcreateNew : createNew,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tdeleteFromList : deleteFromList\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Create new SpecialMealIssue object \r\n * @memberof SpecialMealIssueFactory\r\n */\r\n\t\tfunction createNew() {\r\n\t\t\treturn GenericModalFactory.createNew(SpecialMealIssue)\r\n\t\t};\r\n\r\n /**\r\n * Extend given SpecialMealIssue object \r\n * @memberof SpecialMealIssueFactory\r\n * @param {object} obj The SpecialMealIssue object that will be extended\r\n * @returns {object} SpecialMealIssue\r\n */ \r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericModalFactory.fromObject(obj,SpecialMealIssue)\r\n\t\t}\r\n \r\n /**\r\n * Delete SpecialMealIssue object from given list\r\n * @memberof SpecialMealIssueFactory\r\n * @param {object} obj The SpecialMealIssue object that will be deleted\r\n * @returns {array} SpecialMealIssues\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\treturn GenericModalFactory.deleteFromList(obj, objList)\r\n\t\t}\r\n /**\r\n * Extend given SpecialMealIssue object List \r\n * @memberof SpecialMealIssueFactory\r\n * @param {object} obj The SpecialMealIssue object that will be extended\r\n * @returns {array} SpecialMealIssues\r\n */ \r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericModalFactory.fromObjectList(objList,SpecialMealIssue)\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('SpecialMealSourceFactory', SpecialMealSourceFactory);\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SpecialMealSourceFactory\r\n * @description \r\n * Manage Report's SpecialMealSources.\r\n * @ngInject\r\n */\r\nfunction SpecialMealSourceFactory(GenericValuesFactory) {\r\n\r\n /**\r\n * Initialiaze SpecialMealSource object \r\n * @memberof SpecialMealSourceFactory\r\n */\r\n\t\tfunction SpecialMealSource() {\r\n\t\t\tthis.Code = null;\r\n\t\t}\r\n\t \r\n\t\tvar callback=SpecialMealSource;\r\n\t\tvar type ='specialMealSources';\r\n\t\t\r\n\t\tvar service = {\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\ttoObjectList : toObjectList,\r\n\t\t\tgetSpecialMealSourcesFromStorage : getSpecialMealSourcesFromStorage,\r\n\t\t\tgetSpecialMealSourcesFromStorageAsStrings : getSpecialMealSourcesFromStorageAsStrings,\r\n\t\t\tsetSpecialMealSourcesToStorage : setSpecialMealSourcesToStorage\r\n\t\t}\r\n \r\n /**\r\n * Create a new SpecialMealSource object \r\n * @memberof SpecialMealSourceFactory\r\n * @returns {object} SpecialMealSource\r\n */\t\r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericValuesFactory.fromObject(obj,callback);\r\n\t\t}\r\n\r\n /**\r\n * Extend given SpecialMealSource object List \r\n * @memberof SpecialMealSourceFactory\r\n * @param {object} obj The SpecialMealSource object that will be extended\r\n * @returns {array} SpecialMealSources\r\n */ \r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericValuesFactory.fromObjectList(objList,callback);\r\n\t\t}\r\n \r\n /**\r\n * Get all the SpecialMealSource's Code from given list\r\n * @memberof SpecialMealSourceFactory\r\n * @param {array} objectList An object list\r\n * @returns {array} SpecialMealSources\r\n */\r\n\t\tfunction toObjectList(objList) {\r\n\t\t\treturn GenericValuesFactory.objList(objList);\r\n\t\t}\r\n\r\n /**\r\n * Get all the SpecialMealSource objects\r\n * @memberof SpecialMealSourceFactory\r\n * @returns {array} SpecialMealSources\r\n */\r\n\t\tfunction getSpecialMealSourcesFromStorage() {\r\n\t\t\treturn GenericValuesFactory.getValuesFromStorage(callback,type);\r\n\t\t}\r\n\r\n /**\r\n * Get all the SpecialMealSource's codes\r\n * @memberof SpecialMealSourceFactory\r\n * @returns {array} SpecialMealSources\r\n */\r\n\t\tfunction getSpecialMealSourcesFromStorageAsStrings() {\r\n\t\t\treturn GenericValuesFactory.getValuesFromStorageAsStrings(callback,type);\r\n\t\t}\r\n\r\n /**\r\n * Set all the SpecialMealSources\r\n * @memberof SpecialMealSourceFactory\r\n * @param {array} objects A list of SpecialMealSources.\r\n */\r\n\t\tfunction setSpecialMealSourcesToStorage(objList) {\r\n\t\t\tGenericValuesFactory.setValuesToStorage(objList,type);\r\n\t\t}\r\n\r\n\treturn service;\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('SpecialMealTypeFactory', SpecialMealTypeFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SpecialMealTypeFactory\r\n * @description \r\n * Manage SpecialMealTypes.\r\n * @ngInject\r\n */\r\nfunction SpecialMealTypeFactory(localStorageMD5Service ) {\r\n\r\n /**\r\n * Initialiaze SpecialMealType object \r\n * @memberof SpecialMealTypeFactory\r\n */\r\n\t\tfunction SpecialMealType() {\r\n\t\t\tthis.Code = null;\r\n\t\t}\r\n\r\n\t\tvar callback=SpecialMealType;\r\n\t\tvar type ='specialMealTypes';\r\n\t\t\t\r\n\t\tvar service = {\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tformObjects : formObjects,\r\n\t\t\ttoObjectList : toObjectList,\r\n\t\t\tgetSpecialMealTypesFromStorage : getSpecialMealTypesFromStorage,\r\n\t\t\tgetSpecialMealTypesFromStorageAsStrings : getSpecialMealTypesFromStorageAsStrings,\r\n\t\t\tsetSpecialMealTypesToStorage : setSpecialMealTypesToStorage,\r\n\t\t\tgetSpecialMealTypesFromStorageAsObjects : getSpecialMealTypesFromStorageAsObjects\r\n\t\t}\r\n\t\r\n /**\r\n * Extend given SpecialMealType object \r\n * @memberof SpecialMealTypeFactory\r\n * @param {object} obj The SpecialMealType object that will be extended\r\n * @returns {object} SpecialMealType\r\n */\r\n\t\tfunction fromObject(obj) {\r\n\t\t\tif (obj == null) return null;\r\n\t\t\tvar specialMealType = new SpecialMealType();\r\n\t\t\tspecialMealType.Code = obj.code + ' - ' + obj.label;\r\n\t\t\treturn specialMealType;\r\n\t\t}\r\n\r\n /**\r\n * Extend given SpecialMealType object list\r\n * @memberof SpecialMealTypeFactory\r\n * @param {array} objList The list of SpecialMealType objects that will be extended\r\n * @returns {object} SpecialMealTypes\r\n */\r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\tif (objList == null) return null;\r\n\r\n\t\t\tvar arrayLength = objList.length;\r\n\t\t\tvar specialMealTypes = [];\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tvar specialMealType = new SpecialMealType();\r\n\t\t\t\tspecialMealType.Code = objList[i].code + ' - ' + objList[i].label;\r\n\t\t\t\tspecialMealTypes.push(specialMealType);\r\n\t\t\t}\r\n\r\n\t\t\treturn specialMealTypes;\r\n\t\t}\r\n\r\n /**\r\n * Extend given SpecialMealType object list\r\n * @memberof SpecialMealTypeFactory\r\n * @param {array} objList The list of SpecialMealType objects that will be extended\r\n * @returns {object} SpecialMealTypes\r\n */\r\n\t\tfunction formObjects(objList) {\r\n\t\t\tif (objList == null) \r\n\t\t\t\treturn null;\r\n\r\n\t\t\tvar arrayLength = objList.length;\r\n\t\t\tvar specialMealTypes = new Array();\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tvar specialMealType = new SpecialMealType();\r\n\t\t\t\tspecialMealType.Code = objList[i].code\r\n\t\t\t\tspecialMealType.Label = objList[i].label;\r\n\t\t\t\tspecialMealTypes.push(specialMealType);\r\n\t\t\t}\r\n\t\t\treturn specialMealTypes;\r\n\t\t}\r\n \r\n \r\n /**\r\n * Get all the SpecialMealType's Code from given list\r\n * @memberof SpecialMealTypeFactory\r\n * @param {array} objectList An object list\r\n * @returns {array} SpecialMealTypes\r\n */\r\n\t\tfunction toObjectList(objList) {\r\n\t\t\tif (specialMealTypeList == null) return null;\r\n\r\n\t\t\tvar arrayLength = specialMealTypeList.length;\r\n\t\t\tvar objList = [];\r\n\r\n\t\t\tfor (var i = 0; i < arrayLength; i++) {\r\n\t\t\t\tobjList.push(specialMealTypeList[i].Code);\r\n\t\t\t}\r\n\r\n\t\t\treturn objList;\r\n\t\t}\r\n\r\n /**\r\n * Get all the SpecialMealType objects\r\n * @memberof SpecialMealTypeFactory\r\n * @returns {array} SpecialMealTypes\r\n */\r\n\t\tfunction getSpecialMealTypesFromStorage() {\r\n\t\t\tvar specialMealTypes = localStorageMD5Service.get('specialMealTypes');\r\n\t\t\treturn fromObjectList(specialMealTypes);\r\n\t\t}\r\n\r\n /**\r\n * Get all the SpecialMealType full objects\r\n * @memberof SpecialMealTypeFactory\r\n * @returns {array} SpecialMealTypes\r\n */\r\n\t\tfunction getSpecialMealTypesFromStorageAsObjects() {\r\n\t\t\tvar specialMealTypes = localStorageMD5Service.get('specialMealTypes');\r\n\t\t\treturn formObjects(specialMealTypes);\r\n\t\t}\r\n\r\n /**\r\n * Get all the SpecialMealType's codes from local storage\r\n * @memberof SpecialMealTypeFactory\r\n * @returns {array} SpecialMealTypes\r\n */\r\n\t\tfunction getSpecialMealTypesFromStorageAsStrings() {\r\n\t\t\tvar result = [];\r\n\t\t\tvar objs = getSpecialMealTypesFromStorage();\r\n\t\t\tfor (var i = 0; i < objs.length; i++) {\r\n\t\t\t\tresult.push(objs[i].Code);\r\n\t\t\t}\r\n\t\t\treturn result;\r\n\t\t}\r\n\r\n \r\n /**\r\n * Set all the SpecialMealTypes\r\n * @memberof SpecialMealTypeFactory\r\n * @param {array} objects A list of SpecialMealTypes.\r\n */\r\n\t\tfunction setSpecialMealTypesToStorage(specialMealTypes) {\r\n\t\t\tlocalStorageMD5Service.set('specialMealTypes', specialMealTypes);\r\n\t\t}\r\n\r\n\treturn service;\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('SupplyCtrl', SupplyCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name SupplyCtrl\r\n * @description \r\n * Manages the Supply Modal View\r\n * @ngInject\r\n */\r\nfunction SupplyCtrl($scope, $timeout, $uibModalInstance, ModalDialogResultFactory, SupplyFactory, ACSupplyFactory, sup) {\r\n\t\t// setup supply types\r\n\t\tvar smts = ACSupplyFactory.getACSuppliesFromStorageAsStrings();\r\n\t\tif (!(smts instanceof Array)) smts = [];\r\n\t\t$scope.supplyTypes = smts;\r\n\r\n\t\t$scope.clearField = clearField;\r\n // clear remarks function\r\n\t\t$scope.clearSupplyRemarks = clearSupplyRemarks;\r\n\r\n\t\tvar result = ModalDialogResultFactory.createNew();\r\n\r\n\t\tif (sup == null) {\r\n\t\t\tresult.Object = SupplyFactory.createNew();\r\n\t\t\tresult.isInsertMode = true;\r\n\t\t} else {\r\n\t\t\tresult.Object = SupplyFactory.fromObject(sup);\r\n\t\t\tresult.isInsertMode = false;\r\n\t\t}\r\n\r\n\t\t$scope.sup = result.Object;\r\n\r\n\t\t$scope.ok = ok;\r\n $scope.cancel = cancel;\r\n\r\n\t\t$timeout(function() {\r\n\t\t\t$('.modal-supplies').find('textarea').each(function(index, item) {\r\n\t\t\t\tif (item.value != '')\r\n\t\t\t\t\tautoAdjustTextarea(item);\r\n\t\t\t});\r\n\t\t}, 500);\r\n \r\n /**\r\n * Clear Field\r\n * @memberof SupplyCtrl\r\n */\r\n function clearField(target, fieldName) {\r\n\t\t\tif (target[fieldName] == null || target[fieldName] == '') return false;\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Please confirm that you wish to clear this field\",\r\n\t\t\t\ttitle: \"Attention\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function() {}\r\n\t\t\t\t\t},\r\n\t\t\t\t\tok: {\r\n\t\t\t\t\t\tlabel: \"Ok\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function() {\r\n\t\t\t\t\t\t\ttarget[fieldName] = null;\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n\t\t}\r\n\r\n /**\r\n * Clear Supply Remarks\r\n * @memberof SupplyCtrl\r\n * @param {object} supply\r\n */\r\n function clearSupplyRemarks(sup) {\r\n\t\t\t$scope.clearField(sup, \"Remarks\");\r\n\t\t\t//sup.Remarks = null;\r\n\t\t}\r\n \r\n /**\r\n * Close modal after u check SupplyType\r\n * @memberof SupplyCtrl\r\n */\r\n function ok() {\r\n\t\t\tif ((result.Object.SupplyType == null) || (result.Object.SupplyType == ''))\r\n\t\t\t\tresult.Object.SupplyType = '-';\r\n\t\t\t$uibModalInstance.close(result);\r\n\t\t}\r\n \r\n /**\r\n * Close modal\r\n * @memberof SupplyCtrl\r\n */\r\n function cancel() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n\r\na3_cabin_reports.factory('SupplyFactory', SupplyFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name SupplyFactory\r\n * @description \r\n * Manage Report's Supplies.\r\n * @ngInject\r\n */\r\nfunction SupplyFactory(GenericModalFactory) {\r\n\r\n /**\r\n * Initialiaze a object \r\n * @memberof SupplyFactory\r\n */\r\n\t\tfunction Supply() {\r\n\t\t\tthis.SupplyType = null;\r\n\t\t\tthis.Remarks = null;\r\n\t\t}\r\n\t\r\n\t\tvar service = {\r\n\t\t\tcreateNew : createNew,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tdeleteFromList : deleteFromList\r\n\t\t}\r\n\t\t\r\n /**\r\n * Initialiaze Supply object \r\n * @memberof SupplyFactory\r\n */\r\n\t\tfunction createNew() {\r\n\t\t\treturn GenericModalFactory.createNew(Supply)\r\n\t\t}\r\n\r\n /**\r\n * Extend given Supply object \r\n * @memberof SupplyFactory\r\n * @param {object} obj The Supply object that will be extended\r\n * @returns {object} Supply\r\n */ \r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericModalFactory.fromObject(obj,Supply)\r\n\t\t}\r\n\r\n /**\r\n * Delete Supply object from given list\r\n * @memberof SupplyFactory\r\n * @param {object} obj The Supply object that will be deleted\r\n * @returns {array} Supplies\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\treturn GenericModalFactory.deleteFromList(obj, objList)\r\n\t\t}\r\n\t\t\r\n /**\r\n * Extend given Supply object List \r\n * @memberof SupplyFactory\r\n * @param {object} obj The Supply object that will be extended\r\n * @returns {array} Supplies\r\n */\r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericModalFactory.fromObjectList(objList,Supply)\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();\r\n","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('TravelValueIncompleteReasonFactory', TravelValueIncompleteReasonFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name TravelValueIncompleteReasonFactory\r\n * @description \r\n * Manage Travel Value Incomplete Reasons.\r\n * @ngInject\r\n */\r\nfunction TravelValueIncompleteReasonFactory(localStorageMD5Service) {\r\n\r\n\t\t\r\n\t\tvar service = {\r\n\t\t\t\tgetReasonsFromStorage : getReasonsFromStorage,\r\n\t\t\t\tsetReasonsToStorage : setReasonsToStorage\r\n\t\t};\r\n\t\r\n /**\r\n * Get all the Travel Value Incomplete Reasons full objects\r\n * @memberof TravelValueIncompleteReasonFactory\r\n * @returns {array} TravelValueIncompleteReasons\r\n */\r\n\t\tfunction getReasonsFromStorage() {\r\n\t\t\tvar results = localStorageMD5Service.get('travelValueIncompleteReasons');\r\n\t\t\treturn (results || []);\r\n\t\t}\r\n\r\n /**\r\n * Set all the Travel Value Incomplete Reasons\r\n * @memberof TravelValueIncompleteReasonFactory\r\n * @param {array} objects A list of TravelValueIncompleteReasons.\r\n */\r\n\t\tfunction setReasonsToStorage(data) {\r\n\t\t\tlocalStorageMD5Service.set('travelValueIncompleteReasons', data);\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('TravelValueSealCtrl', TravelValueSealCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name TravelValueSealCtrl\r\n * @description \r\n * Manages Travel Value Seal Modal View\r\n * @ngInject\r\n */\r\nfunction TravelValueSealCtrl($scope, $uibModalInstance, ModalDialogResultFactory, TravelValueSealFactory, tvs) {\r\n\r\n\t\tvar result = ModalDialogResultFactory.createNew();\r\n\r\n\t\tif (tvs == null) {\r\n\t\t\tresult.Object = TravelValueSealFactory.createNew();\r\n\t\t\tresult.isInsertMode = true;\r\n\t\t} else {\r\n\t\t\tresult.Object = TravelValueSealFactory.fromObject(tvs);\r\n\t\t\tresult.isInsertMode = false;\r\n\t\t}\r\n\r\n\t\t$scope.tvs = result.Object;\r\n\r\n\t\t$scope.ok = ok; \r\n $scope.cancel = cancel;\r\n \r\n /**\r\n * Close modal after u check Label\r\n * @memberof TravelValueSealCtrl\r\n */\r\n function ok() {\r\n\t\t\tif ((result.Object.Label == null) || (result.Object.Label == ''))\r\n\t\t\t\tresult.Object.Label = '-';\r\n\t\t\t$uibModalInstance.close(result);\r\n\t\t}\r\n\r\n\r\n /**\r\n * Close modal \r\n * @memberof TravelValueSealCtrl\r\n */ \r\n function cancel() {\r\n\t\t\t$uibModalInstance.close(null);\r\n\t\t}\r\n\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.factory('TravelValueSealFactory', TravelValueSealFactory);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc factory\r\n * @name TravelValueSealFactory\r\n * @description \r\n * Manage Report's TravelValueSeals.\r\n * @ngInject\r\n */\r\nfunction TravelValueSealFactory(GenericModalFactory) {\r\n\r\n /**\r\n * Initialiaze TravelValueSeal object \r\n * @memberof TravelValueSealFactory\r\n */\r\n\t\tfunction TravelValueSeal() {\r\n\t\t\tthis.Id = null;\r\n\t\t\tthis.Position = null;\r\n\t\t\tthis.SealFound = null;\r\n\t\t\tthis.SealLeft = null;\r\n\t\t}\r\n\r\n\t\tvar service = {\r\n\t\t\tcreateNew : createNew,\r\n\t\t\tfromObject : fromObject,\r\n\t\t\tfromObjectList : fromObjectList,\r\n\t\t\tdeleteFromList : deleteFromList\r\n\t\t}\r\n\t\t\t\r\n /**\r\n * Create new TravelValueSeal object \r\n * @memberof TravelValueSealFactory\r\n */\r\n\t\tfunction createNew() {\r\n\t\t\treturn GenericModalFactory.createNew(TravelValueSeal)\r\n\t\t}\r\n\r\n /**\r\n * Extend given TravelValueSeal object \r\n * @memberof TravelValueSealFactory\r\n * @param {object} obj The TravelValueSeal object that will be extended\r\n * @returns {object} TravelValueSeal\r\n */ \r\n\t\tfunction fromObject(obj) {\r\n\t\t\treturn GenericModalFactory.fromObject(obj,TravelValueSeal)\r\n\t\t}\r\n\r\n /**\r\n * Delete TravelValueSeal object from given list\r\n * @memberof TravelValueSealFactory\r\n * @param {object} obj The TravelValueSeal object that will be deleted\r\n * @returns {array} TravelValueSeals\r\n */\r\n\t\tfunction deleteFromList(obj, objList) {\r\n\t\t\treturn GenericModalFactory.deleteFromList(obj, objList)\r\n\t\t}\r\n\t\r\n /**\r\n * Extend given TravelValueSeal object List \r\n * @memberof TravelValueSealFactory\r\n * @param {object} obj The TravelValueSeal object that will be extended\r\n * @returns {array} TravelValueSeals\r\n */ \r\n\t\tfunction fromObjectList(objList) {\r\n\t\t\treturn GenericModalFactory.fromObjectList(objList,TravelValueSeal)\r\n\t\t}\r\n\r\n\t\treturn service;\r\n\t}\r\n\r\n})();","(function() {\r\n 'use strict';\r\n \r\na3_cabin_reports.controller('UPGDCtrl', UPGDCtrl);\r\n\r\n /**\r\n * @memberof CabinReports\r\n * @ngdoc controller\r\n * @name UPGDCtrl\r\n * @description \r\n * Manages the UPGD Modal View\r\n * @ngInject\r\n */\r\nfunction UPGDCtrl(upgradedPassenger, report, paxInfo, PaxInfoFactory, $scope, $uibModalInstance) {\r\n // get eligible passengers\r\n \r\n var paxInfo = paxInfo;\r\n var eligiblePassengers = getEligiblePassengers();\r\n \r\n $scope.eligiblePassengers = eligiblePassengers;\r\n $scope.clearUPGDRemarks = clearUPGDRemarks;\r\n\r\n\t\tvar result = {};\r\n\r\n\t\tif (upgradedPassenger == null) {\r\n $scope.editMode = false;\r\n\t\t\tresult.Object = null;\r\n\t\t\tresult.isInsertMode = true;\r\n\t\t} else {\r\n $scope.editMode = true;\r\n result.Object = Object.assign({}, upgradedPassenger);\r\n result.Object.check = true;\r\n\t\t\tresult.isInsertMode = false;\r\n\t\t}\r\n\r\n $scope.upgradedPassenger = result.Object;\r\n \r\n $scope.showUpgradeWarning = false;\r\n $scope.showUpgradeError = false;\r\n $scope.submitUpgrade = submitUpgrade;\r\n $scope.saveUpgrade = saveUpgrade;\r\n $scope.cancel = cancel;\r\n\r\n\t\t\r\n\r\n /**\r\n * Clear Field\r\n * @memberof UPGDCtrl\r\n */\r\n function clearField(target, fieldName) {\r\n\t\t\tif (target[fieldName] == null || target[fieldName] == '') return false;\r\n\t\t\tbootbox.dialog({\r\n\t\t\t\tmessage: \"Please confirm that you wish to clear this field\",\r\n\t\t\t\ttitle: \"Attention\",\r\n\t\t\t\tbuttons: {\r\n\t\t\t\t\tcancel: {\r\n\t\t\t\t\t\tlabel: \"Cancel\",\r\n\t\t\t\t\t\tclassName: \"btn-default\",\r\n\t\t\t\t\t\tcallback: function() {}\r\n\t\t\t\t\t},\r\n\t\t\t\t\tok: {\r\n\t\t\t\t\t\tlabel: \"Ok\",\r\n\t\t\t\t\t\tclassName: \"btn-warning\",\r\n\t\t\t\t\t\tcallback: function() {\r\n\t\t\t\t\t\t\ttarget[fieldName] = null;\r\n\t\t\t\t\t\t\t$scope.$apply();\r\n\t\t\t\t\t\t\treturn true;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t});\r\n }\r\n \r\n /**\r\n * fix any input into 000A format\r\n * @memberof UPGDCtrl\r\n */\r\n function formatSeatInput(){\r\n\t\t\tvar missingZeroes = 4 - $scope.upgradedPassenger.UpgradedSeatNo.length;\r\n\t\t\tfor (var i=0; i