Beispiel #1
0
        public async Task UpdateVehicleListAsync()
        {
            this.IsBusy = true;

            try
            {
                if (!_reachability.IsConnected())
                {
                    _toast.Show("No internet connection!");
                }
                else
                {
                    var vehicleViews = await _gatewayService.GetVehicleViewsAsync();

                    var vehicleViewVehicles = new Dictionary <string, IEnumerable <Models.BaseVehicle> >(vehicleViews.Count());

                    foreach (var vehicleView in vehicleViews)
                    {
                        vehicleViewVehicles.Add(vehicleView.Title, await _gatewayService.GetVehiclesAsync(vehicleView.Title));
                    }

                    var vehiclesAndTrailers = vehicleViewVehicles.SelectMany(vvv => vvv.Value).DistinctBy(v => v.ID);
                    var vehicles            = vehiclesAndTrailers.Where(bv => !bv.IsTrailer).Select(bv => new Models.Vehicle(bv));

                    if (vehicles != null)
                    {
                        await _vehicleRepository.DeleteAllAsync();

                        try
                        {
                            await _vehicleRepository.InsertAsync(vehicles);
                        }
                        catch (Exception ex)
                        {
                            MvxTrace.Error("\"{0}\" in {1}.{2}\n{3}", ex.Message, "VehicleRepository", "InsertAsync", ex.StackTrace);
                            throw;
                        }

                        Vehicles = _originalVehicleList = await _vehicleRepository.GetAllAsync();

                        //Recalls the filter text if there is text in the search field.
                        if (VehicleSearchText != null)
                        {
                            this.FilterList();
                        }
                    }
                }

                await UpdateSafetyProfilesAsync();
            }
            finally
            {
                this.IsBusy = false;
            }
        }
Beispiel #2
0
 public async Task UpdateInstructionsListAsync()
 {
     if (!_reachability.IsConnected())
     {
         _toast.Show("No internet connection!");
     }
     else
     {
         // Force a poll for instructions
         await _gatewayPollingService.PollForInstructionsAsync();
     }
 }
Beispiel #3
0
        public async Task EnterCodeAsync()
        {
            if (string.IsNullOrWhiteSpace(this.CustomerCode))
            {
                //TODO: probably should additionally implement presentation layer required field validation so we don't even get this far.
                await _userInteraction.AlertAsync("To register this device, submit a customer code");

                return;
            }

            if (!_reachability.IsConnected())
            {
                await _userInteraction.AlertAsync("To set-up this device, a connection to the internet is required");
            }
            else
            {
                bool success = false;
                ProgressTitle   = _progressTitleForCustomerCode;
                ProgressMessage = _progressMessageForCustomerCode;

                this.IsBusy = true;

                try
                {
                    success = await this.SetupDeviceAsync();
                }
                catch (Exception ex)
                {
                    MvxTrace.Warning("Exception while setting up device: {0} at {1}", ex.Message, ex.StackTrace);
                    success       = false;
                    _errorMessage = _unexpectedErrorMessage;
                }
                finally
                {
                    this.IsBusy = false;
                }

                if (success)
                {
                    ProgressTitle   = _progressTitleForCheckIn;
                    ProgressMessage = _progressMessageForCheckIn;
                    IsBusy          = true;
                    await _navigationService.MoveToNextAsync();

                    IsBusy = false;
                }
                else
                {
                    await _userInteraction.AlertAsync(_errorMessage);
                }
            }
        }
Beispiel #4
0
        public async Task <AuthenticationResult> AuthenticateAsync(string passcode)
        {
            Mvx.Trace("Looking up passcode in local repository");
            var driver = await GetMatchingDriverAsync(passcode);

            // driver not in local DB, update from BlueSphere (if we can)
            if (driver == null && _reachability.IsConnected())
            {
                Mvx.Trace("Driver not found - refreshing driver list from Gateway");
                await UpdateDriversAsync();

                Mvx.Trace("Driver list updated - looking up passcode in local repository again");
                driver = await GetMatchingDriverAsync(passcode);
            }

            // the passcode doesn't match any driver we know about
            if (driver == null)
            {
                return new AuthenticationResult {
                           Success = false, AuthenticationFailedMessage = "The driver passcode you submitted doesn't exist, check the passcode and try again."
                }
            }
            ;

            // check if driver is licensed
            if (await IsLicensedAsync(driver))
            {
                return new AuthenticationResult {
                           Success = true, AuthenticationFailedMessage = null, Driver = driver
                }
            }
            ;
            else
            {
                return new AuthenticationResult {
                           Success = false, AuthenticationFailedMessage = "Request for user license failed. Please contact Proteo for licensing queries."
                }
            };
        }
Beispiel #5
0
        /// <summary>
        /// This method uploads the database to the FTP server under the Android Device ID
        /// </summary>
        /// <param name="databasePath">The locations of the mySql Database</param>
        public async Task <bool> UploadDiagnosticsAsync(string databasePath)
        {
            if (!_reachability.IsConnected())
            {
                return(false);
            }

            var config = await _repositories.ConfigRepository.GetAsync();

            if (config == null ||
                string.IsNullOrWhiteSpace(config.FtpUrl) ||
                string.IsNullOrWhiteSpace(config.FtpUsername) ||
                string.IsNullOrWhiteSpace(config.FtpPassword))
            {
                await Mvx.Resolve <ICustomUserInteraction>().AlertAsync("Your FTP credentials have not been set up, you cannot upload support data until they have been set up.");

                return(false);
            }

            bool       success      = false;
            LogMessage exceptionMsg = null;

            try
            {
                var uriString = string.Format("{0}/{1}/{2}", config.FtpUrl, _deviceInfo.AndroidId, Path.GetFileName(databasePath));
                var uri       = new Uri(uriString);
                success = await _upload.UploadFileAsync(uri, config.FtpUsername, config.FtpPassword, databasePath);
            }
            catch (Exception ex)
            {
                exceptionMsg = _loggingService.GetExceptionLogMessage(ex);
            }

            if (exceptionMsg != null)
            {
                await _loggingService.LogEventAsync(exceptionMsg);
            }

            return(success);
        }
Beispiel #6
0
        public async Task UploadDiagnosticsAsync()
        {
            if (!_reachability.IsConnected())
            {
                await _userInteraction.AlertAsync("You need a connection to the internet to submit diagnostics.");
            }
            else
            {
                bool success = false;
                this.IsBusy = true;

                try
                {
                    success = await _diagnosticsService.UploadDiagnosticsAsync(_dataService.DatabasePath);
                }
                catch (Exception)
                {
                    success = false;
                }
                finally
                {
                    this.IsBusy = false;
                }

                if (success)
                {
                    await _userInteraction.AlertAsync("Support diagnostic information uploaded successfully.", null, "Upload Complete");

                    await _navigationService.MoveToNextAsync();
                }
                else
                {
                    await _userInteraction.AlertAsync(_unexpectedErrorMessage);
                }
            }
        }
Beispiel #7
0
        public async Task PollForInstructionsAsync()
        {
            try
            {
                if (!_reachability.IsConnected())
                {
                    return;
                }

                using (await _lock.LockAsync())
                {
                    var data = await _repositories.ApplicationRepository.GetAllAsync();

                    var applicationProfile = data.FirstOrDefault();
                    if (applicationProfile != null)
                    {
                        _dataRetention = applicationProfile.DataRetention;
                        _dataSpan      = applicationProfile.DataSpan;
                    }
                }

                Mvx.Trace("Begin Polling For Instructions");
                string exceptionMsg = null;

                try
                {
                    if (!_dataRetention.HasValue || !_dataSpan.HasValue)
                    {
                        var applicationProfile = await _repositories.ApplicationRepository.GetAsync();

                        _dataRetention = applicationProfile.DataRetention;
                        _dataSpan      = applicationProfile.DataSpan;
                    }

                    var instructionNotificationsToPublish = new Dictionary <Guid, Messages.GatewayInstructionNotificationMessage.NotificationCommand>();

                    // Remove any existing instructions that fall before the data retention period
                    Mvx.Trace("Removing obsolete instructions.");
                    var obsoleteInstructions = await _repositories.MobileDataRepository.GetObsoleteInstructionsAsync(_dataRetention.Value);

                    Mvx.Trace("{0} obsolete instructions to remove.", obsoleteInstructions.Any() ? obsoleteInstructions.Count().ToString() : "No");

                    foreach (var instruction in obsoleteInstructions)
                    {
                        await _repositories.MobileDataRepository.DeleteAsync(instruction);

                        instructionNotificationsToPublish[instruction.ID] = Messages.GatewayInstructionNotificationMessage.NotificationCommand.Delete;
                    }

                    // Call to BlueSphere to check for instructions
                    var instructions = await _gatewayService.GetDriverInstructionsAsync(
                        _infoService.CurrentVehicleRegistration,
                        _infoService.CurrentDriverID.Value,
                        DateTime.Today.AddDays(-_dataRetention.Value),
                        DateTime.Today.AddDays(_dataSpan.Value));

                    // Check if we have anything in the response
                    if (!instructions.Any())
                    {
                        Mvx.Trace("No instructions were available.");
                    }
                    else
                    {
                        Mvx.Trace(string.Format("Successfully pulled {0} instructions.", instructions.Count()));

                        var currentViewModel = _customPresenter.CurrentFragmentViewModel as BaseFragmentViewModel;
                        var manifestInstructionVMsForNotification = new List <ManifestInstructionViewModel>(instructions.Count());

                        // We have a response so check what we need to do (Save/Update/Delete)
                        foreach (var instruction in instructions)
                        {
                            var popupNotifyInstruction = false;

                            Mvx.Trace("started processing instruction." + instruction.ID);

                            instruction.VehicleId = _infoService.CurrentVehicleID.Value;

                            switch (instruction.SyncState)
                            {
                            case SyncState.Add:

                                Mvx.Trace("started adding instruction." + instruction.ID);
                                var instructionToAdd = await _repositories.MobileDataRepository.GetByIDAsync(instruction.ID);

                                if (instructionToAdd == null)
                                {
                                    try
                                    {
                                        await _repositories.MobileDataRepository.InsertAsync(instruction);
                                    }
                                    catch (Exception ex)
                                    {
                                        MvxTrace.Error("\"{0}\" in {1}.{2}\n{3}", ex.Message, "MobileDataRepository", "InsertAsync", ex.StackTrace);
                                        throw;
                                    }

                                    popupNotifyInstruction = true;
                                }

                                Mvx.Trace("completed adding instruction." + instruction.ID);
                                instructionNotificationsToPublish[instruction.ID] = Messages.GatewayInstructionNotificationMessage.NotificationCommand.Add;
                                break;

                            case SyncState.Update:
                                Mvx.Trace("started updating instruction." + instruction.ID);
                                var instructionToUpdate = await _repositories.MobileDataRepository.GetByIDAsync(instruction.ID);

                                if (instructionToUpdate != null)
                                {
                                    var progress = instructionToUpdate.ProgressState;
                                    await _repositories.MobileDataRepository.DeleteAsync(instructionToUpdate);

                                    instruction.ProgressState           = progress;
                                    instruction.LatestDataChunkSequence = instructionToUpdate.LatestDataChunkSequence;
                                }

                                try
                                {
                                    await _repositories.MobileDataRepository.InsertAsync(instruction);
                                }
                                catch (Exception ex)
                                {
                                    MvxTrace.Error("\"{0}\" in {1}.{2}\n{3}", ex.Message, "MobileDataRepository", "InsertAsync", ex.StackTrace);
                                    throw;
                                }

                                popupNotifyInstruction = true;
                                Mvx.Trace("completed updating instruction." + instruction.ID);
                                instructionNotificationsToPublish[instruction.ID] = Messages.GatewayInstructionNotificationMessage.NotificationCommand.Update;
                                break;

                            case SyncState.Delete:
                                Mvx.Trace("started deleting instruction." + instruction.ID);
                                var oldInstruction = await _repositories.MobileDataRepository.GetByIDAsync(instruction.ID);

                                if (oldInstruction != null)
                                {
                                    await _repositories.MobileDataRepository.DeleteAsync(oldInstruction);

                                    if (oldInstruction.ProgressState != InstructionProgress.Complete)
                                    {
                                        popupNotifyInstruction = true;
                                    }
                                }

                                Mvx.Trace("completed deleting instruction." + instruction.ID);
                                instructionNotificationsToPublish[instruction.ID] = Messages.GatewayInstructionNotificationMessage.NotificationCommand.Delete;
                                break;
                            }

                            if (popupNotifyInstruction)
                            {
                                manifestInstructionVMsForNotification.Add(new ManifestInstructionViewModel(currentViewModel, instruction));
                            }
                        }

                        Mvx.Trace("Successfully inserted/updated/deleted instructions in repository.");

                        //Acknowledge that they are on the Device (Not however acknowledged by the driver)
                        await this.AcknowledgeInstructionsAsync(instructions);

                        Mvx.Trace("Successfully sent device acknowledgement.");

                        if (manifestInstructionVMsForNotification.Any())
                        {
                            var notifiedInstructionVMs = await Mvx.Resolve <ICustomUserInteraction>().PopUpInstructionNotificationAsync(
                                manifestInstructionVMsForNotification,
                                title: "Manifest Update",
                                okButton: "Acknowledge");

                            await this.SendReadChunksAsync(notifiedInstructionVMs);
                        }

                        if (instructionNotificationsToPublish.Any())
                        {
                            _messenger.Publish(new Messages.GatewayInstructionNotificationMessage(this, instructionNotificationsToPublish));
                        }
                    }
                }
                catch (Exception ex)
                {
                    // catch and log the error, but this will not acknowledge the message so we can try again
                    exceptionMsg = ex.Message;
                }

                if (exceptionMsg != null)
                {
                    await _loggingService.LogEventAsync("Gateway Polling Processing Failed", LogType.Error, exceptionMsg);
                }
            }
            catch (Exception ex)
            {
                // if there is an error here, then just continue as this is probably related to a connection issue
                MvxTrace.Warning("Failed to poll for instructions: {0} at {1}", ex.Message, ex.StackTrace);
            }
        }
Beispiel #8
0
        /// <summary>
        /// This method sends photos and comments to bluesphere, if the sender is on an
        /// instruction page then the instruction will be associated with the photos
        /// </summary>
        /// <param name="comment">The comment for the photos</param>
        /// <param name="photos">The collection of photos to be sent up</param>
        public async Task SendPhotoAndCommentAsync(string comment, List <Image> photos, Guid driverID, string driverDisplayName, IEnumerable <MobileData> mobileDatas)
        {
            if (!_reachability.IsConnected())
            {
                return;
            }

            Mvx.Resolve <IToast>().Show("Now uploading images");

            Encoding encoding      = Encoding.UTF8;
            int      uploadedCount = 0;

            var config = await _repositories.ConfigRepository.GetAsync();

            if (config == null && string.IsNullOrWhiteSpace(config.HEUrl))
            {
                await Mvx.Resolve <ICustomUserInteraction>().AlertAsync("Your HE Url has not been setup, you cannot upload images unless it has been setup.");

                return;
            }

            UploadCameraImageObject imageUpload = new UploadCameraImageObject();

            imageUpload.Smp              = _gpsService.GetSmpData(Enums.ReportReason.Comment);
            imageUpload.ID               = Guid.NewGuid();
            imageUpload.DriverTitle      = driverDisplayName;
            imageUpload.DriverId         = driverID;
            imageUpload.Pictures         = photos;
            imageUpload.Comment          = comment;
            imageUpload.DateTimeOfUpload = DateTime.Now;

            //If the user is not on the manifest screen they should be on an instruction page
            if (mobileDatas != null)
            {
                imageUpload.MobileApplicationIDs = mobileDatas.Select(md => md.ID).ToList();
                imageUpload.OrderIDs             = string.Join(",", mobileDatas.SelectMany(md => md.Order.Items.Select(i => i.ItemIdFormatted)));
            }

            foreach (var image in imageUpload.Pictures)
            {
                var postParameters = new Dictionary <string, string>();
                postParameters.Add("filename", image.Filename);
                postParameters.Add("fileformat", "jpg");
                postParameters.Add("MwfInternalId", image.ID.ToString());
                postParameters.Add("DriverName", imageUpload.DriverTitle);
                postParameters.Add("PhotoComment", string.IsNullOrEmpty(imageUpload.Comment) ? string.Empty : imageUpload.Comment);
                postParameters.Add("PhotoDateTime", imageUpload.DateTimeOfUpload.ToString("o"));
                postParameters.Add("Latitude", (_gpsService.GetLatitude() ?? 0d).ToString());
                postParameters.Add("Longitude", (_gpsService.GetLongitude() ?? 0d).ToString());
                postParameters.Add("MobileApplicationDataIds", (imageUpload.MobileApplicationIDs == null) ? string.Empty : string.Join(",", imageUpload.MobileApplicationIDs.Select(x => x.ToString())));
                postParameters.Add("HEOrderIds", string.IsNullOrWhiteSpace(imageUpload.OrderIDs) ? string.Empty : imageUpload.OrderIDs.ToString());

                Uri postUrl = new Uri(string.Format("{0}/Mwf/ReceiveMwfPhoto.aspx", config.HEUrl));

                using (var request = new HttpRequestMessage(HttpMethod.Post, postUrl.AbsoluteUri))
                    using (var fileContent = new ByteArrayContent(image.Bytes))
                    {
                        var formContent = new MultipartFormDataContent();

                        foreach (var postParameter in postParameters)
                        {
                            formContent.Add(new StringContent(postParameter.Value), postParameter.Key);
                        }

                        fileContent.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment")
                        {
                            FileName = image.Filename,
                        };

                        formContent.Add(fileContent);

                        request.Content = formContent;
                        try
                        {
                            var response = await _httpService.SendAsyncPlainResponse <HttpResponseMessage>(request);

                            if (response.StatusCode == HttpStatusCode.OK)
                            {
                                await _loggingService.LogEventAsync("Image sent successfully.", Enums.LogType.Info);

                                uploadedCount++;
                            }
                            else
                            {
                                await _loggingService.LogEventAsync(string.Format("Image failed to send, Status Code: {0}.", response.StatusCode), Enums.LogType.Error);
                            }
                        }
                        catch (Exception ex)
                        {
                            throw;
                        }
                    }
            }

            if (uploadedCount != imageUpload.Pictures.Count)
            {
                await Mvx.Resolve <ICustomUserInteraction>().AlertAsync(string.Format("Only {0} of {1} were uploaded successful.", uploadedCount, imageUpload.Pictures.Count), title: "Upload Failed");
            }
            else
            {
                Mvx.Resolve <IToast>().Show("Successfully uploaded images");
            }
        }
Beispiel #9
0
        public async Task UploadLoggedEventsAsync()
        {
            if (_isSubmitting)
            {
                return;
            }

            _isSubmitting = true;

            try
            {
                var events = await _loggedRepository.GetAllAsync();

                if (events != null && events.Count() > 0)
                {
                    events = events.OrderBy(e => e.LogDateTime);
                }

                if (events != null && events.Any())
                {
                    if (!_reachability.IsConnected())
                    {
                        return;
                    }

                    var deviceIdentifier = _deviceInfo.GetDeviceIdentifier();

                    foreach (var e in events)
                    {
                        int messageLength = e.Message.Length;
                        var deviceMessage = new DeviceLogMessage
                        {
                            Message          = e.Message.Substring(0, Math.Min(messageLength, MAX_MESSAGE_LENGTH)),
                            LogDateTime      = e.LogDateTime,
                            DeviceIdentifier = deviceIdentifier
                        };

                        var isException = false;

                        try
                        {
                            var response = await _gatewayService.PostLogMessageAsync(deviceMessage);

                            isException = !response.Succeeded;
                        }
                        catch
                        {
                            isException = true;
                        }

                        if (isException)
                        {
                            await this.HandleLoggingFailureAsync(e, events.ToList());
                        }

                        await _loggedRepository.DeleteAsync(e);
                    }
                }
            }
            finally
            {
                _isSubmitting = false;
            }
        }
Beispiel #10
0
        public async Task UpdateTrailerListAsync()
        {
            if (!_reachability.IsConnected())
            {
                _toast.Show("No internet connection!");
                return;
            }

            this.ProgressMessage = "Updating Trailers.";
            this.IsBusy          = true;

            try
            {
                IDictionary <string, IEnumerable <Models.BaseVehicle> > vehicleViewVehicles;

                try
                {
                    var vehicleViews = await _gatewayService.GetVehicleViewsAsync();

                    vehicleViewVehicles = new Dictionary <string, IEnumerable <Models.BaseVehicle> >(vehicleViews.Count());

                    foreach (var vehicleView in vehicleViews)
                    {
                        vehicleViewVehicles.Add(vehicleView.Title, await _gatewayService.GetVehiclesAsync(vehicleView.Title));
                    }
                }
                catch (TaskCanceledException)
                {
                    // Although we have used reachability to determine that there is an available network connection,
                    // it is still possible for the data fetch to fail which triggers a TaskCanceledException.
                    _toast.Show("Connection failure!");
                    return;
                }

                var vehiclesAndTrailers = vehicleViewVehicles.SelectMany(vvv => vvv.Value).DistinctBy(v => v.ID);
                var trailers            = vehiclesAndTrailers.Where(bv => bv.IsTrailer).Select(bv => new Models.Trailer(bv));

                if (trailers != null)
                {
                    await _repositories.TrailerRepository.DeleteAllAsync();

                    try
                    {
                        await _repositories.TrailerRepository.InsertAsync(trailers);
                    }
                    catch (Exception ex)
                    {
                        MvxTrace.Error("\"{0}\" in {1}.{2}\n{3}", ex.Message, "TrailerRepository", "InsertAsync", ex.StackTrace);
                        throw;
                    }

                    await GetTrailerModelsAsync();

                    //Recalls the filter text if there is text in the search field.
                    if (TrailerSearchText != null)
                    {
                        this.FilterList();
                    }
                }
            }
            finally
            {
                this.IsBusy = false;
            }

            await UpdateVehicleListAsync();
            await UpdateSafetyProfilesAsync();
        }