| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860 | using System;using System.Collections.Generic;using System.Linq;using System.Threading;using System.Threading.Tasks;using Xamarin.Forms;using InABox.Core;using InABox.Clients;using InABox.Mobile;using Comal.Classes;using InABox.Configuration;using XF.Material.Forms.UI.Dialogs;namespace comal.timesheets{    public partial class MainPage : BasePage    {        #region Fields        bool bUpdatingTimesheet = false;        bool midnightTimerOn = false;        DateTime oneSecondBeforeMidnight = DateTime.Today.AddSeconds(864399);        bool clockedOffInLast5Seconds = false;        bool bRecentlyUpdatedTiles = false;        string matchedDeviceName = "";        int notCount = 1;        private TimeSheet _currenttimesheet = null;                #endregion        #region Constructor                public MainPage() : base()        {            MobileLogging.Log("MainPage.Create");            InitializeComponent();                        MobileLogging.Log("MainPage.InitNotificationCentre");            InitNotificationCentre();                        MobileLogging.Log("MainPage.Subscribe");            MessagingCenter.Subscribe<App>(this, App.MessageOnResume,                (o) =>                {                    if (!App.GPS.RecentlyLocated)                        App.GPS.GetLocation();                    RefreshScreen();                }            );            MobileLogging.Log("MainPage.NotifyChanges");            NotifyChanges();            MobileLogging.Log("MainPage.Create Done");                    }                private void NotifyChanges()        {            Task.Run(() =>            {                string changes = NotifyMobileChanges.Notifiy();                if (!string.IsNullOrWhiteSpace(changes))                    Device.BeginInvokeOnMainThread(() =>                    {                        DisplayAlert("Latest changes", changes, "OK");                    });            });        }        #endregion        #region OnAppearing and Display        private SelectionPage _selectionpage = null;        protected override void OnAppearing()        {            MobileLogging.Log("MainPage.Appearing");            if (_selectionpage == null)            {                BackButtonEnabled = App.IsSharedDevice;                EnableModules();                StartMonitoringNotifications();                StartPromptingForUpdates();                App.Data.GPSLocationUpdated += OnGPSLocationUpdated;                App.Data.BluetoothScanFinished += OnBluetothScanFinished;                //LoadHRToDos(); to be uncommented when ready for roll out                CheckTimeSheet();            }            _selectionpage = null;            MobileLogging.Log("MainPage.refreshScreen");            RefreshScreen();            MobileLogging.Log("MainPage.Base.OnAppearing");            base.OnAppearing();            MobileLogging.Log("MainPage.OnAppearing Done");        }        private IMaterialModalPage _snackbar = null;                 protected override void OnDisappearing()        {            base.OnDisappearing();                        //App.Data.GPSLocationUpdated -= OnGPSLocationUpdated;            //App.Data.BluetoothScanFinished -= OnBluetothScanFinished;                        _canceltasks.Cancel();        }                private void OnBluetothScanFinished(BluetoothEventArgs args)        {            Dispatcher.BeginInvokeOnMainThread(RefreshScreen);        }        private void OnGPSLocationUpdated(GPSEventArgs args)        {            Dispatcher.BeginInvokeOnMainThread(RefreshScreen);        }        private void EnableModules()        {            void SetupClockOnButton(bool disable)            {                LogoRow.Height = disable ? 150 : 0;                ClockOnRow.Height = disable ? 0 : new GridLength(5.5, GridUnitType.Star);                JobRow.Height = disable ? 0 : 55;                TaskRow.Height = disable ? 0 : 55;              }                        SetupClockOnButton(InABox.Core.Security.IsAllowed<IsJobOnlyEmployee>());            Assignments.IsVisible = InABox.Core.Security.CanView<Assignment>();            Deliveries.IsVisible = InABox.Core.Security.CanView<Delivery>();            Forms.IsVisible = InABox.Core.Security.CanView<DigitalForm>();            Equipment.IsVisible = InABox.Core.Security.CanView<Equipment>();            InOut.IsVisible = InABox.Core.Security.IsAllowed<CanViewInOutBoard>();            Manufacturing.IsVisible = InABox.Core.Security.CanView<ManufacturingPacket>();            Products.IsVisible = InABox.Core.Security.CanView<Product>();            PurchaseOrders.IsVisible = InABox.Core.Security.CanView<PurchaseOrder>();            StoreRequis.IsVisible = InABox.Core.Security.CanView<Requisition>();            MyTasks.IsVisible = InABox.Core.Security.CanView<Kanban>();            Warehousing.IsVisible = InABox.Core.Security.CanView<StockWarehouse>();        }                protected override void UpdateTransportStatus()        {            base.UpdateTransportStatus();            RefreshScreen();        }                private CancellationTokenSource _canceltasks = new CancellationTokenSource();        private int _notificationcount = 0;                private void StartMonitoringNotifications()        {            //notifications are allowed to upload once every 30 seconds            // This will eventually be replaced with websocket pushes            // but we're not ready for that yet :-(            var token = _canceltasks.Token;            Task.Run(                () =>                {                    while (!_canceltasks.Token.IsCancellationRequested)                    {                        App.Data.Notifications.Refresh(true);                        if (App.Data.Notifications.Items.Count != _notificationcount)                        {                            Dispatcher.BeginInvokeOnMainThread(() =>                            {                                _notificationcount = App.Data.Notifications.Items.Count;                                Notifications.Indicator = _notificationcount.ToString();                            });                        }                        Task.Delay(TimeSpan.FromSeconds(30), token)                            .Wait(token);                    }                },                token            );        }                private void StartPromptingForUpdates()        {            var token = _canceltasks.Token;            Task.Run(                () =>                {                    while (!token.IsCancellationRequested)                    {                        bool isLatest = MobileUtils.AppVersion.IsUsingLatestVersion().Result;                        if (!isLatest)                        {                            string latestVersionNumber = MobileUtils.AppVersion.GetLatestVersionNumber().Result;                            string chosenOption = DisplayActionSheet(                                $"Version {latestVersionNumber} Available. Update now?",                                "You will be reminded again in 10 minutes.", null, "Yes", "No").Result;                            if (String.Equals(chosenOption,"Yes"))                                Dispatcher.BeginInvokeOnMainThread(() => { MobileUtils.AppVersion.OpenAppInStore(); });                        }                        Task.Delay(TimeSpan.FromMinutes(10), token)                            .Wait(token);                    }                                    }                , token            );        }                private void RefreshScreen()        {                        bool GateReady = CheckLocation();            var location = GetAddress();                        Title = App.Data.Me != null ? App.Data.Me.Name : "(Not Logged In)";            ClockOnButton.IsEnabled = App.Data.IsConnected() && GateReady;                        ClockOnOffLabel.Text = GateReady ? _currenttimesheet == null ? "CLOCK ON" : "CLOCK OFF" : "PLEASE WAIT";            CurrentLocation.Text = location.ToUpper().Contains("ERROR")                ? "Unknown Address"                : location;                        ClockOnButton.BackgroundColor = App.Data.IsConnected() && GateReady                 ? _currenttimesheet == null                     ? Color.FromHex("#e6e6fa")                     : Color.FromHex("#15C7C1")                 : Color.Silver;                        ClockOnButton.BorderColor = App.Data.IsConnected() && GateReady                 ? _currenttimesheet == null                     ? Color.FromHex("#96969a")                     : Color.FromHex("#059791")                 : Color.Gray;                        addNoteBtn.IsEnabled = App.Data.IsConnected() && _currenttimesheet != null;            jobBtn.IsEnabled = App.Data.IsConnected() && _currenttimesheet != null;            taskBtn.IsEnabled = App.Data.IsConnected() && _currenttimesheet != null;                        jobBtn.Text = ((_currenttimesheet?.JobID ?? Guid.Empty) != Guid.Empty)                ? $"{_currenttimesheet.JobLink.JobNumber}: {_currenttimesheet.JobLink.Name}"                : "No Job Selected";                        Assignments.IsEnabled = App.Data.IsConnected();            Deliveries.IsEnabled = App.Data.IsConnected();            Forms.IsEnabled = App.Data.IsConnected();            //Equipment.IsEnabled = App.Data.IsConnected();            InOut.IsEnabled = App.Data.IsConnected();            Manufacturing.IsEnabled = App.Data.IsConnected();            MyHR.IsEnabled = App.Data.IsConnected();            Notifications.IsEnabled = App.Data.IsConnected();            Products.IsEnabled = App.Data.IsConnected();            PurchaseOrders.IsEnabled = App.Data.IsConnected();            Site.IsEnabled = App.Data.IsConnected();            StoreRequis.IsEnabled = App.Data.IsConnected();            MyTasks.IsEnabled = App.Data.IsConnected();            Warehousing.IsEnabled = App.Data.IsConnected();        }                #endregion        #region Clock on/off                private void CheckTimeSheet()        {            if (App.Data.IsConnected())            {                var client = new Client<TimeSheet>();                var filter = new Filter<TimeSheet>(x => x.EmployeeLink.ID).IsEqualTo(App.Data.Me.ID)                    .And(x => x.Date).IsEqualTo(DateTime.Today)                    .And(x => x.Finish).IsEqualTo(TimeSpan.Zero);                var table = client.Query(filter);                _currenttimesheet = table.Rows.FirstOrDefault()?.ToObject<TimeSheet>();            }            var token = _canceltasks.Token;            Task.Run(                () =>                {                    while (!token.IsCancellationRequested)                    {                        if (_currenttimesheet != null)                        {                            if (_currenttimesheet.Date != DateTime.Today)                            {                                InABox.Core.Location here = new InABox.Core.Location()                                {                                    Latitude = App.GPS.Latitude,                                    Longitude = App.GPS.Longitude,                                    Timestamp = DateTime.Now                                };                                _currenttimesheet.FinishLocation = here;                                _currenttimesheet.Finish = TimeSpan.FromDays(1).Subtract(TimeSpan.FromSeconds(1));                                new Client<TimeSheet>().Save(_currenttimesheet,                                    "Closing Timesheet at Modnight on Mobile Device");                                CreateTimeSheet(_currenttimesheet.JobLink.ID, _currenttimesheet.JobLink.JobNumber, _currenttimesheet.JobLink.Name, here, here.Address, "Creating Timeheet at Midnight on Mobile Device");                            }                        }                        Task.Delay(TimeSpan.FromMinutes(1), token).Wait(token);                    }                },                token            );        }                private DateTime _debounce = DateTime.MinValue;                async void ClockOnOff_Clicked(object sender, System.EventArgs e)        {                        if (_debounce > DateTime.Now.Subtract(TimeSpan.FromMilliseconds(500)))                return;            _debounce = DateTime.MaxValue;                        string chosenOption = _currenttimesheet != null                ? await DisplayActionSheet("Clock off?", "Cancel", null, "Continue", "Cancel")                : "Continue";                        if (!String.Equals(chosenOption, "Continue"))            {                _debounce = DateTime.Now;                return;            }                        try            {                using (await MaterialDialog.Instance.LoadingDialogAsync(message: $"Clocking {(_currenttimesheet == null ? "On" : "Off")}"))                {                    InABox.Core.Location here = new InABox.Core.Location()                    {                        Latitude = App.GPS.Latitude,                        Longitude = App.GPS.Longitude,                        Timestamp = DateTime.Now                    };                                        if (_currenttimesheet != null)                    {                        FinishTimeSheet(here);                    }                    else                    {                        if (!InABox.Core.Security.IsAllowed<CanBypassBluetoothGates>())                        {                            var tracker = App.Data.BluetoothGates.FirstOrDefault(x => App.Bluetooth.Devices.Contains(x.DeviceID));                            if (tracker != null)                                CreateTimeSheet(tracker.JobID, tracker.JobNumber, tracker.JobName, here, App.GPS.Address, "Clocking On");                        }                        else                        {                            if ((!App.GPS.Latitude.Equals(0.0F)) && (!App.GPS.Longitude.Equals(0.0F)))                            {                                var job = await ChooseNearbyJob(here);                                CreateTimeSheet(job?.ID ?? Guid.Empty, job?.JobNumber ?? "", job?.Name ?? "" , here, App.GPS.Address, "Clocking On");                            }                        }                    }                    Dispatcher.BeginInvokeOnMainThread(RefreshScreen);                }            }            catch (Exception ex)            {                InABox.Mobile.MobileLogging.Log(ex);            }                        _debounce = DateTime.Now;         }                                private void FinishTimeSheet(InABox.Core.Location here)        {            if ((_currenttimesheet == null) || (_currenttimesheet.ID == Guid.Empty))            {                _currenttimesheet = null;                return;            }            try            {                if (ZeroLengthTimesheet())                    new Client<TimeSheet>().Delete(_currenttimesheet, "Deleted due to zero duration timesheet");                else                {                    _currenttimesheet.Finish =                        new TimeSpan(DateTime.Now.TimeOfDay.Hours, DateTime.Now.TimeOfDay.Minutes, 0);                    _currenttimesheet.FinishLocation = here;                    bUpdatingTimesheet = true;                    new Client<TimeSheet>().Save(_currenttimesheet, "Clocking Off");                }                _currenttimesheet = null;            }            catch (Exception ex)            {                InABox.Mobile.MobileLogging.Log(ex);            }        }                #endregion        #region Utilities                private void InitNotificationCentre()        {            // LocalNotificationCenter.Current.NotificationActionTapped += (Plugin.LocalNotification.EventArgs.NotificationActionEventArgs e) =>            // {            //     if (MainPageUtils.DetermineCorrectPage(e) != null)            //     {            //         Device.BeginInvokeOnMainThread(() =>            //         {            //             Navigation.PushAsync(MainPageUtils.DetermineCorrectPage(e));            //         });            //     }            // };            //            // MainPageUtils.OnMainPageNotificationsChanged += RefreshOnNotificationsChange;        }                private void CheckNotificationsPushed(CoreTable table)        {            // try            // {            //     if (!Application.Current.Properties.ContainsKey("LastPushedNotifications"))            //     {            //         Application.Current.Properties.Add("LastPushedNotifications", DateTime.Now);            //     }            //     DateTime lastPushed = DateTime.Parse(Application.Current.Properties["LastPushedNotifications"].ToString());            //     List<NotificationShell> toNotify = new List<NotificationShell>();            //     foreach (CoreRow row in table.Rows)            //     {            //         List<object> list = row.Values;            //         DateTime created = DateTime.Parse(list[3].ToString());            //         if (created > new DateTime(2022, 8, 22)) // prevent spam from buildup of old notifications before this is released            //         {            //             if (created > lastPushed)            //             {            //                 if (list[1] == null) list[1] = "";            //                 if (list[2] == null) list[2] = "";            //                 if (list[3] == null) list[3] = DateTime.MinValue;            //                 if (list[4] == null) list[4] = "";            //                 if (list[5] == null) list[5] = "";            //                 if (list[6] == null) list[6] = Guid.Empty;            //            //                 NotificationShell shell = new NotificationShell            //                 {            //                     ID = Guid.Parse(list[0].ToString()),            //                     Sender = list[1].ToString(),            //                     Title = list[2].ToString(),            //                     Created = DateTime.Parse(list[3].ToString()),            //                     EntityType = list[5].ToString(),            //                     EntityID = Guid.Parse(list[6].ToString())            //                 };            //                 toNotify.Add(shell); //add notification to be pushed            //             }            //         }            //     }            //     if (toNotify.Count > 0)            //         PushNotificationsAsync(toNotify);            // }            // catch { }        }        private async Task PushNotificationsAsync(List<NotificationShell> shells)        {            // try            // {            //     int count = 1;            //            //     foreach (NotificationShell shell in shells)            //     {            //         var notification = new NotificationRequest            //         {            //             BadgeNumber = 1,            //             Description = shell.Title,            //             Title = "New PRS Notification: ",            //             ReturningData = shell.EntityID.ToString() + "$" + shell.EntityType,            //             NotificationId = count,            //         };            //         count++;            //         NotificationImage img = new NotificationImage();            //         img.ResourceName = "icon16.png";            //         notification.Image = img;            //            //         await LocalNotificationCenter.Current.Show(notification);            //     }            //     Application.Current.Properties["LastPushedNotifications"] = DateTime.Now;            // }            // catch { }        }                private async Task<JobShell> ChooseNearbyJob(InABox.Core.Location here)        {            var nearbyjobs = App.Data.Jobs.Where(x => here.DistanceTo(x.Location, UnitOfLength.Kilometers) < 1.0F)                .ToArray();            if (nearbyjobs.Length > 1)            {                Dictionary<String, JobShell> dict = new Dictionary<string, JobShell>();                foreach (var job in nearbyjobs)                    dict[job.DisplayName] = job;                string chosenOption = await DisplayActionSheet("Choose job site", "Cancel", null, dict.Keys.ToArray());                if (string.IsNullOrEmpty(chosenOption) || chosenOption.Equals("Cancel"))                    return null;                return dict[chosenOption];            }            return nearbyjobs.FirstOrDefault();        }        void AddNote_Tapped(System.Object sender, System.EventArgs e)        {            if (_currenttimesheet == null)                return;            var notepage = new TimeSheetNotePage(_currenttimesheet);            Navigation.PushAsync(notepage);        }        private void TaskBtn_Tapped(object sender, EventArgs e)        {            _selectionpage = new TaskSelectionPage( (task) =>                {                    if (_currenttimesheet != null)                    {                        // Not sure hwat to do here...                    }                }            );            Navigation.PushAsync(_selectionpage);        }        // private async void RequestUserInput(Guid taskID)        // {        //     const string addtask = "Change current assignment task";        //     const string newassignment = "Start a new assignment with this task";        //     string chosenOption = await DisplayActionSheet("Choose an option", "Cancel", null, addtask, newassignment);        //     switch (chosenOption)        //     {        //         case addtask:        //             MainPageUtils.ChangeAssignmentTask(taskID);        //             break;        //         case newassignment:        //             MainPageUtils.SaveCurrentAssignment("PRS Mobile main screen - saving assignment on task change", true);        //             MainPageUtils.CreateNewAssignment(Guid.Empty, taskID);        //             break;        //         default:        //             break;        //     }        // }        private void JobBtn_Tapped(object sender, EventArgs e)        {            _selectionpage = new JobSelectionPage(                (job) =>                {                    if (_currenttimesheet != null)                    {                        if (ZeroLengthTimesheet())                        {                            _currenttimesheet.JobLink.ID = job?.ID ?? Guid.Empty;                            _currenttimesheet.JobLink.JobNumber = job?.JobNumber ?? "";                            _currenttimesheet.JobLink.Name = job?.Name ?? "";                            new Client<TimeSheet>().Save(_currenttimesheet,"Updated Job Number via mobile device");                        }                        else                        {                            var here = new Location()                            {                                Latitude = App.GPS.Latitude,                                Longitude = App.GPS.Longitude,                                Address = App.GPS.Address,                                Timestamp = App.GPS.TimeStamp                            };                            FinishTimeSheet(here);                            CreateTimeSheet(job?.ID ?? Guid.Empty, job?.JobNumber ?? "", job?.Name ?? "", here, here.Address,                                "Switched Jobs via Mobile Device");                        }                    }                }                            );            Navigation.PushAsync(_selectionpage);        }                // private bool CheckTimeSheetAgainstGates(TimeSheet timesheet)        // {        //     DateTime now = DateTime.Now;        //        //     //var timesheet = CurrentTimeSheet();        //        //     //Can't confirm if there is no timesheet        //     if (timesheet == null)        //         return false;        //        //     // Can't confirm if there are no devices        //     if (App.Bluetooth.Devices.Length == 0)        //         return false;        //        //     if (App.Data.Gates == null)        //         return false;        //        //     long tsTicks = timesheet.Date.Add(timesheet.Start).Ticks;        //     long btTicks = App.Bluetooth.TimeStamp.Ticks;        //        //     if (Math.Abs(tsTicks - btTicks) > new TimeSpan(0, 2, 0).Ticks)        //         return false;        //        //     CoreRow firstgate = null;        //     List<String> gates = new List<string>();        //     // Scan every located d        //     foreach (var device in App.Bluetooth.Devices)        //     {        //         CoreRow gate = App.Data.Gates?.Rows.FirstOrDefault(r => r.Get<JobTracker, String>(c => c.TrackerLink.DeviceID) == device);        //         if (gate != null)        //         {        //        //             if ((gate.Get<JobTracker, bool>(x => x.IsJobSite) == true) && (firstgate == null))        //                 firstgate = gate;        //        //             gates.Add(gate.Get<JobTracker, String>(x => x.Gate));        //         }        //     }        //     if (gates.Any())        //     {        //         timesheet.Gate = String.Join(", ", gates.OrderBy(x => x));        //         if (firstgate != null)        //         {        //             timesheet.JobLink.ID = firstgate.Get<JobTracker, Guid>(x => x.JobLink.ID);        //             timesheet.JobLink.JobNumber = firstgate.Get<JobTracker, String>(x => x.JobLink.JobNumber);        //             timesheet.JobLink.Name = firstgate.Get<JobTracker, String>(x => x.JobLink.Name);        //         }        //         return true;        //         //new Client<TimeSheet>().Save(timesheet, "Confirmed Gate Entry by Bluetooth Tracker", (o, e) => { });        //     }        //        //     return false;        //        // }        private bool ZeroLengthTimesheet()        {            if (_currenttimesheet == null)                return true;                        if (!String.IsNullOrWhiteSpace(_currenttimesheet.Notes))                return false;                        if (_currenttimesheet.Date.Equals(DateTime.Today))            {                var diff = (DateTime.Now.TimeOfDay - _currenttimesheet.Start).TotalSeconds;                if (Math.Abs(diff) < 120.0F)                    return true;            }            return false;        }        private async void CreateTimeSheet(Guid jobid, string jobnumber, String jobname, InABox.Core.Location location, String address, String auditmessage)        {            try            {                _currenttimesheet = new TimeSheet();                _currenttimesheet.EmployeeLink.ID = App.Data.Me.ID;                _currenttimesheet.Date = DateTime.Today;                TimeSpan tod = DateTime.Now - DateTime.Today;                tod = new TimeSpan(tod.Hours, tod.Minutes, 0);                _currenttimesheet.Start = tod;                _currenttimesheet.StartLocation = location;                _currenttimesheet.JobLink.ID = jobid;                _currenttimesheet.JobLink.JobNumber = jobnumber;                _currenttimesheet.JobLink.Name = jobname;                _currenttimesheet.Address = address;                _currenttimesheet.SoftwareVersion = MobileUtils.AppVersion.InstalledVersionNumber + MobileUtils.GetDeviceID();                //if (ClientFactory.IsAllowed<AllowTimeSheetRollover>()) CheckTimeSheetAgainstGates(timesheet);                bUpdatingTimesheet = true;                new Client<TimeSheet>().Save(_currenttimesheet, auditmessage);            }            catch (Exception ex)            {                InABox.Mobile.MobileLogging.Log(ex);            }        }        private bool CheckLocation()        {            // a 15 minute timeout is awfully long for this process.            // The App times tick over every 30 seconds, so surely we can            // drop this to max 1 or 2 minutes..            // Also, we would expect the GPS / Bluetooth subsystems to take care            // of purging stale data                        if (InABox.Core.Security.IsAllowed<CanBypassBluetoothGates>())                return App.GPS.TimeStamp > DateTime.Now.Subtract(new TimeSpan(0, 15, 0));            if (App.Bluetooth.TimeStamp < DateTime.Now.Subtract(new TimeSpan(0, 15, 0)))                return false;            return App.Data.BluetoothGates.Any(x =>                App.Bluetooth.DetectedBlueToothMACAddresses.Contains(x.DeviceID));        }        private String GetAddress()        {            if (InABox.Core.Security.IsAllowed<CanBypassBluetoothGates>())            {                if (App.GPS.TimeStamp < DateTime.Now.Subtract(new TimeSpan(0, 5, 0)))                {                    App.GPS.GetLocation(true);                    return "Searching for GPS";                }                return App.GPS.Address;            }            else            {                var gate = App.Data.BluetoothGates.FirstOrDefault(x =>                    App.Bluetooth.DetectedBlueToothMACAddresses.Contains(x.DeviceID));                return gate?.Gate ?? "Looking for Gate";            }        }                private async void LoadHRToDos()        {            try            {                await Task.Run(() =>                {                    Thread.Sleep(10000);                    if (App.Data.UpdateHRItemsNeedingAttention())                    {                        string message = "You have HR Items needing attention. Open My HR now?";                        Device.BeginInvokeOnMainThread(async () =>                        {                            string chosenOption = await DisplayActionSheet(message, "Cancel", null, "Yes", "No");                            switch (chosenOption)                            {                                case "Cancel":                                    break;                                case "No":                                    break;                                default:                                    break;                                case "Yes":                                    MyHRHome myHRHome = new MyHRHome();                                    Navigation.PushAsync(myHRHome);                                    break;                            }                        });                    }                });            }            catch { }        }        #endregion        private void Settings_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new SettingsPage());        }                private void Assignments_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new AssignmentList());        }        private void Deliveries_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new DeliveryModule());        }                private void Equipment_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new EquipmentModule());        }        private void Forms_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new KanbanForms());            //Navigation.PushAsync(new DigitalFormsPicker("Kanban");        }                private void InOut_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new StaffStatusPage());        }        private void Manufacturing_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new ManufacturingScreen());        }        private void MyHR_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new MyHRHome());        }        private void Notifications_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new NotificationList());        }        private void Products_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new ProductListTwo());        }        private void PurchaseOrders_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new PurchaseOrderModule());        }        private void Site_OnTapped(object sender, EventArgs e)        {            Guid jobid =                 _currenttimesheet?.JobLink.ID                     ?? new LocalConfiguration<SiteModuleSettings>().Load().JobID;                        Navigation.PushAsync(                new SiteModule()                {                    JobID = jobid                }            );        }        private void StoreRequis_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new StoreRequiList());        }        private void MyTasks_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new TasksList());        }        private void Warehousing_OnTapped(object sender, EventArgs e)        {            Navigation.PushAsync(new Warehousing2());        }    }}
 |