/*================================================================================================================\ + + Project : GODATA-VECV + Filename : LiveTracking.js + Module Name : Tracking + Purpose : For live monitoring and history tracking of users in outside field using GPS locator. + Coded By : Jitendra Tiwari & Pankaj Khandal + +================================================================================================================*/ /** * For live monitoring and history tracking of users in outside field using GPS locator. * @module TrackingModule */ // Global variables var ccplMap = null, markerImagePath = "../../Scripts/map_api/icons/red_blank.png", markerTransImgPath = "../../Scripts/map_api/icons/red_blink.gif", defaultLat = 26.912285124827, defaultLng = 75.7873203125; var SecurityToken, utcMinutes, UserId, UserRole; var counter = 0; var xhr_exportExport; var activeRequest_WorkingHours; /*================================================Map Function=============================================*/ /** * Load google map on page. * @method initMap * @param {String} id HTML element id where map is loaded. * @for LiveTracking */ function initMap(id) { var mapOptions = { mapPro: 'googleMap', mapDiv: document.getElementById(id), zoom: 10, centerLatitude: defaultLat, centerLongitude: defaultLng, mapType: 'ROADMAP' }; ccplMap = new vtsMap(mapOptions); } /** * Function used to add/show multiple devices on map. * @method addMultipleDeviceToMap * @param {Object} jsonObject Required json object for adding device on map. * @for LiveTracking */ function addMultipleDeviceToMap(jsonObject) { //console.log(jsonObject); if (ccplMap) { //console.log("add device"); ccplMap.addMultipleUnit(jsonObject); } } /** * Function used to remove all existing markers from map. * @method removeAllUnit * @for LiveTracking */ function removeAllUnit() { if (ccplMap) { ccplMap.removeAllUnit(); } } /** * Function used to remove a particular path from map based on a ID. * @method removeUnit * @param {String} unitID ID of a marker * @for LiveTracking */ function removeUnit(unitID) { if (ccplMap) { ccplMap.removeUnit(unitID); } } /** * Function used to remove all existing path from map. * @method showHiddenUnit * @param {Object} unitOptions options for a marker * @for LiveTracking */ function showHiddenUnit(unitOptions) { if (ccplMap) { ccplMap.showHiddenUnit(unitOptions); } } /** * Function used to move device from one location to another on map. * @method moveUnitPoints * @param {Object} jsonObject Required json object for adding device on map. * @for LiveTracking */ function moveUnitPoints(jsonObject) { // console.log(jsonObject); if (ccplMap) { ccplMap.moveMultipleUnit(jsonObject, 10); } } /** * Function used to set device location to center on map. * @method setMapLocationCenter * @param {String} id DeviceId * @for LiveTracking */ function setMapLocationCenter(id) { if (ccplMap) { ccplMap.setUnitCenter(id); } } /** * Function to Add Kendo Window. * @method addKendoWindowToDiv * @param {String} divId Id of Kendo Window * @param {String} titleText Title Of Kendo Window * @param {String} width width Of Kendo Window * @param {String} left left Of Kendo Window * @param {String} top top Of Kendo Window * @for ManageFleet */ function addKendoWindowToDiv(divId, titleText, width, left) { $(divId).kendoWindow({ width: width, title: titleText, modal: true, resizable: false, draggable: true, position: { top: 95, left: left } }); } /** * Function to Set Kendo Window Title. * @method SetKendoWindowTitle * @param {String} divId Id of Kendo Window * @param {String} titleText Title Of Kendo Window * @for ManageFleet */ function SetKendoWindowTitle(divId, titleText) { var dialog = $(divId).data("kendoWindow"); dialog.title(titleText); } /** * Close the kendo window. * @method closeWindow * @param divId : Id which we want to close kendowindo. * @for NonVecvUserManagement */ function closeWindow(divId) { $(divId).data("kendoWindow").close(); } /** * Function used to dynamically update info window on map. * @method updateInfoWindow * @param {String} alias Device alias. * @param {String} description Updated info description. * @for LiveTracking */ function updateInfoWindow(alias, description) { if (ccplMap) { ccplMap.updateInfoWindow(alias, description); } } /*================================================End=============================================*/ /*===============================================Device RESTful API===================================*/ /** * Creating a Model for showing data on Live Tracking page. (Dynamic UI) * @class LiveTracking * @constructor */ function LiveTrackingModel() { 'use strict'; var self = this; self.chosenEmployee = ko.observable(); self.userRole = ko.observable(); //ViewModel self.OrganizationName = ko.observable(); self.DealerDealerName = ko.observable(); self.ServiceEngineerContactNumber = ko.observable(); self.ServiceEngineerId = ko.observable(); self.ServiceEngineerName = ko.observable(); self.ServiceEngineerImeiNumber = ko.observable(); self.IsConnected = ko.observable(); self.VanRegistrationNumber = ko.observable(); self.RegionId = ko.observable(); self.RegionName = ko.observable(); self.Message = ko.observable(); self.BatteryStatus = ko.observable(); self.GpsStatus = ko.observable(); self.IsCharging = ko.observable(); self.VanStartTime = ko.observable(); self.VanEndTime = ko.observable(); self.employees = ko.observableArray([]); /** * Function used to show device detail on page. * @method showDeviceDetail * @param {Object} employee Chosen device object. * @for LiveTracking */ self.showEmployeeDetail = function (employee) { self.chosenEmployee(employee).ServiceEngineerId(employee.ServiceEngineerId).ServiceEngineerName(employee.ServiceEngineerName).DealerDealerName(employee.DealerDealerName).ServiceEngineerContactNumber(employee.ServiceEngineerContactNumber).ServiceEngineerImeiNumber(employee.ServiceEngineerImeiNumber).VanRegistrationNumber(employee.VanRegistrationNumber).OrganizationName(employee.OrganizationName).Message(employee.Message); updateInfoWindow(employee.ServiceEngineerDeviceAlias, $("#divDetails").html()); setMapLocationCenter(employee.ServiceEngineerDeviceAlias); } /** * Function used to trigger row click event. * @method triggerRow * @param {String} currObj HTML element id. * @for LiveTracking */ self.triggerRow = function (rowId) { //console.log(rowId); // Triggering click event when marker on map is clicked $("#tableDevices tbody tr[id=" + rowId + "] td").trigger('click'); } self.saveWorkingHours = function (vanID, van_start_working_hours, van_end_working_hours) { addKendoWindowToDiv("#divShowDealerLocation", "Set Van Inactive Hours", "433px", 250); $("#divShowDealerLocation").parent().addClass("responsive_popup") //addClass for respond the menu // Get selected row if (activeRequest_WorkingHours && activeRequest_WorkingHours.readystate != 4) { activeRequest_WorkingHours.abort(); } activeRequest_WorkingHours = $.ajax({ type: "GET", url: "/Tracking/WorkingHours?van_start_working_hours=" + van_start_working_hours + "&van_end_working_hours=" + van_end_working_hours, success: function (data) { $("#divShowDealerLocation").html(''); $("#divShowDealerLocation").html(data); $("#hdnStartTime").val(van_start_working_hours); //open form in new dialog box $("#divShowDealerLocation").data("kendoWindow").open(); openKendoWindowInCenter("#divShowDealerLocation"); SetKendoWindowTitle("#divShowDealerLocation", "Set Van Inactive Duration"); $("#hdnVanId").val(vanID); }, error: function (data) { console.log(data); } }); } /** * Getting all the employees list and populating the html on page. * @method getAllEmployees * @for LiveTracking */ self.getAllEmployees = function () { $("#div_load").show(); // Showing loading //console.log(counter); SecurityToken = securityToken; utcMinutes = parseInt(UtcMinutes, 10); UserId = userId; UserRole = userRole.toLowerCase(); self.userRole(UserRole); //var dealerName = $("#input_dealers").val(), //vanCity = $('#input_vanCities').val(), //vanState = $('#input_vanStates').val(); var vanState = $("#stateCombobox").data("kendoComboBox").text(); var vanCity = $("#cityCombobox").data("kendoComboBox").text(); var dealerName = $("#dealerCombobox").data("kendoComboBox").text(); if (dealerName == '') { dealerName = 'All'; //$("#input_dealers").val('All'); } if (vanCity == '') { vanCity = 'All'; //$("#input_vanCities").val('All'); } if (vanState == '') { vanState = 'All'; //$("#input_vanStates").val('All'); } $.ajax({ type: "POST", url: WCFRESTURL.GetUsersListWithCurrentTrackingData, data: { Token: SecurityToken, UtcMinute: utcMinutes, UserId: UserId, DealerNameParam: dealerName, VanCityParam: vanCity, VanStateParam: vanState }, dataType: "json", success: function (data) { removeAllUnit(); if (data.ListUsers != null || data.status == 1) { //console.log(data); if (counter == 0) { var jsonObject = []; for (var index = 0; index < data.ListUsers.length; index++) { jsonObject.push({ unitID: data.ListUsers[index].ServiceEngineerDeviceAlias, unitName: data.ListUsers[index].ServiceEngineerName, unitImage: markerImagePath, unitLatitude: defaultLat, unitLongitude: defaultLng, transparentImage: markerTransImgPath, unitDescription: "", triggerInfo: function (id) { self.triggerRow(id); } }); data.ListUsers[index].IsConnected = 0; data.ListUsers[index].UserId = UserRole; } //console.log(jsonObject); addMultipleDeviceToMap(jsonObject); //var employeeList = self.employees(); //self.employees([]).employees(employeeList); //self.employees([]).employees(data.ListUsers); } var finalEmployeeList = ko.utils.arrayFilter(data.ListUsers, function (item) { return item.ServiceEngineerId != null; }); self.employees(finalEmployeeList); self.getUpdatedLocation(data.ListTracking); } else { alert("No Data Available!"); } }, complete: function () { $('#nodata_msg').hide(); $('#divNoDataFound').hide(); if (UserRole == 'dealer') { $('#batteryColumn').hide(); } $("#div_load").hide(); // Hiding loading }, error: function (jqXHR, textStatus, errorThrown) { } }); } /** * Function used to check the connection of device and update device status accordingly. * @method checkConnection * @for LiveTracking */ self.checkConnection = function (deviceId, isConnected, logTime, BatteryStatus, GpsStatus, IsCharging) { //console.log(deviceId, isConnected, logTime, BatteryStatus, GpsStatus, IsCharging); // Setting the IsConnected Bit as boolean TRUE/FALSE. var finalIsConnected = (isConnected == 'True') ? (finalIsConnected = true) : (finalIsConnected = false); //console.log(deviceId + " : " + isConnected); $.each(self.employees(), function (index, item) { var resultItem = item; if (item.ServiceEngineerDeviceAlias == deviceId) { resultItem.IsConnected = finalIsConnected; resultItem.Message = logTime; resultItem.BatteryStatus = BatteryStatus; resultItem.GpsStatus = GpsStatus; resultItem.IsCharging = IsCharging; self.employees()[index] = resultItem; //console.log(resultItem); } }); } /** * Function used to sort the particular column asc/desc order * @method sortJSON * @for LiveTracking */ self.sortJSON = function (data, key, way) { return data.sort(function (a, b) { var x = a[key]; var y = b[key]; if (way === '123') { return ((x < y) ? -1 : ((x > y) ? 1 : 0)); } if (way === '321') { return ((x > y) ? -1 : ((x < y) ? 1 : 0)); } }); } /** * The function searches over the array by certain field value, * and replaces occurences with the parameter provided. * * @param string field Name of the object field to compare * @param string oldvalue Value to compare against * @param string newvalue Value to replace mathes with * @for LiveTracking */ self.replaceByValue = function (json, field, oldvalue, newvalue) { for (var k = 0; k < json.length; ++k) { if (oldvalue == json[k][field]) { json[k][field] = newvalue; } } return json; } /** * Function used to get updated location of devices. * @method getUpdatedLocation * @for LiveTracking */ self.getUpdatedLocation = function (data) { var jsonMapLocation = []; $.each(data, function (index, item) { jsonMapLocation.push({ unitID: item.DeviceAlias, unitLatitude: item.Latitude, unitLongitude: item.Longitude }); //BatteryStatus, GpsStatus, IsCharging self.checkConnection(item.DeviceAlias, item.IsConnected, item.LogTime, item.BatteryStatus, item.GpsStatus, item.IsCharging); }) var employeeList = self.employees(); var employeeList = self.sortJSON(employeeList, 'IsConnected', '321'); // 123 or 321 var employeeList = self.replaceByValue(employeeList, 'BatteryStatus', null, 0); // replacing 'null' values with '0' self.employees([]).employees(employeeList); //self.filterUsers(); //setTimeout(function () { moveUnitPoints(jsonMapLocation); //}, 2000) } /** * To get filter parameters and export report. * @method exportReport * @for DealerWiseCallDetails */ self.exportReport = function () { SecurityToken = securityToken; utcMinutes = parseInt(UtcMinutes, 10); UserId = userId; UserRole = userRole.toLowerCase(); self.userRole(UserRole); var vanState = $("#stateCombobox").data("kendoComboBox").text(); var vanCity = $("#cityCombobox").data("kendoComboBox").text(); var dealerName = $("#dealerCombobox").data("kendoComboBox").text(); if (dealerName == '') { dealerName = 'All'; //$("#input_dealers").val('All'); } if (vanCity == '') { vanCity = 'All'; //$("#input_vanCities").val('All'); } if (vanState == '') { vanState = 'All'; //$("#input_vanStates").val('All'); } // sending ajax request to export ICR Unique Users and Data Usage to Excel, and hadling its completion if (xhr_exportExport && xhr_exportExport.readystate != 4) { xhr_exportExport.abort(); } xhr_exportExport = $.ajax({ type: "POST", url: "/Tracking/ExportReport/", data: { vanState: vanState, vanCity: vanCity, dealerName: dealerName }, success: function (data) { // making the generated Excel available for downloading. window.location.href = data; }, complete: function () { }, error: function (data) { console.log("Error in Export to Excel"); } }); } //================== FILTERS Section Start ========================= /** * To populate state combobox. * @method loadStateChoices * @for LiveTracking */ self.loadStateChoices = function () { //$("#div_load").show(); // Showing loading SecurityToken = securityToken; utcMinutes = parseInt(UtcMinutes, 10); UserId = userId; $.ajax({ type: "POST", url: WCFRESTURL.GetStateListIdWise, data: { Token: SecurityToken, UtcMinutes: utcMinutes, UserId: UserId }, dataType: "json", success: function (data) { $("#stateCombobox").kendoComboBox({ dataTextField: "StateAlias", dataValueField: "StateId", filter: "contains", dataSource: data, //select: onSelect, change: function () { // loading cities according to state id self.loadCityChoices($("#stateCombobox").val()); self.loadDealerChoices($("#stateCombobox").data("kendoComboBox").text(), $("#cityCombobox").data("kendoComboBox").text()); }, //close: onClose, //open: onOpen, //filtering: onFiltering, //dataBound: onDataBound }); }, complete: function () { //$("#stateCombobox").data('kendoComboBox').select(0); self.loadCityChoices($("#stateCombobox").val()); //$("#div_load").hide(); // Hiding loading }, error: function (jqXHR, textStatus, errorThrown) { } }); } /** * To populate city combobox. * @method loadCityChoices * @param {String} stateId id of state * @for LiveTracking */ self.loadCityChoices = function (stateId) { //$("#div_load").show(); // Showing loading SecurityToken = securityToken; utcMinutes = parseInt(UtcMinutes, 10); UserId = userId; $.ajax({ type: "POST", url: WCFRESTURL.GetCityListStateIdWise, data: { Token: SecurityToken, UtcMinutes: utcMinutes, UserId: UserId, StateId: stateId }, dataType: "json", success: function (data) { $("#cityCombobox").kendoComboBox({ dataTextField: "CityName", dataValueField: "CityId", filter: "contains", dataSource: data, //select: onSelect, change: function () { self.loadDealerChoices($("#stateCombobox").data("kendoComboBox").text(), $("#cityCombobox").data("kendoComboBox").text()); }, //close: onClose, //open: onOpen, //filtering: onFiltering, //dataBound: onDataBound }); }, complete: function () { $("#cityCombobox").data("kendoComboBox").text(''); self.loadDealerChoices($("#stateCombobox").val(), $("#cityCombobox").val()); //$("#div_load").hide(); // Hiding loading }, error: function (jqXHR, textStatus, errorThrown) { } }); } /** * To populate city combobox. * @method loadCityChoices * @param {String} state state-name * @param {String} city city-name * @for LiveTracking */ self.loadDealerChoices = function (state, city) { //$("#div_load").show(); // Showing loading SecurityToken = securityToken; utcMinutes = parseInt(UtcMinutes, 10); UserId = userId; //console.log(state + ' : ' + city); $.ajax({ type: "POST", url: WCFRESTURL.GetDealerStateCityWise, data: { Token: SecurityToken, UtcMinutes: utcMinutes, UserId: UserId, DealerStateParam: state, DealerCityParam: city }, dataType: "json", success: function (data) { $("#dealerCombobox").kendoComboBox({ dataTextField: "DealerDealerName", dataValueField: "DealerId", filter: "contains", dataSource: data, //select: onSelect, //change: onChange, //close: onClose, //open: onOpen, //filtering: onFiltering, //dataBound: onDataBound }); }, complete: function () { $("#dealerCombobox").data("kendoComboBox").text(''); $("#div_load").hide(); // Hiding loading }, error: function (jqXHR, textStatus, errorThrown) { } }); } //================== FILTERS Section End ========================= // Set interval to get updated location of devices setInterval(function () { self.getAllEmployees(); }, 1000 * 60 * 5); // Populating Filters on page. self.loadStateChoices(); //self.loadCityChoices($("#stateCombobox").val()); //self.loadDealerChoices($("#stateCombobox").val(), $("#cityCombobox").val()); } /*=====================================================End============================================*/ /*============================================Device List Searching=========================================*/ /** * Function used to trigger row click event. * @method initSearch * @param {String} keyCode Input key code. * @param {String} sValue text to be search. * @for LiveTracking */ function initSearch(keyCode, sValue) { var $rows = $('#tableDevices tbody tr'); var jThis; if (keyCode != 8 && keyCode != 46) { $rows.each(function () { jThis = $(this); if (jThis.is(':visible')) { var oLabel = jThis.find('label').text(); if (oLabel.length > 0) { if (oLabel.toLowerCase().indexOf(sValue.toLowerCase()) >= 0) { jThis.show(); } else { jThis.hide(); } } } }); } else { $rows.each(function () { jThis = $(this); var oLabel = jThis.find('label').text(); if (oLabel.length > 0) { if (oLabel.toLowerCase().indexOf(sValue.toLowerCase()) >= 0) { jThis.show(); } else { jThis.hide(); } } }); } } /** * Bind textbox keyup event for searching. * @event keyup * @for LiveTracking */ $('#txtSearch').keyup(function (event) { var sValue = $.trim($(this).val()); initSearch(event.keyCode, sValue); }).keydown(function () { }).focus(function () { $(this).select(); }); /*=================================================End=================================================*/