Ver código fonte

PRS MOBILE - error logging

Nick-PRSDigital@bitbucket.org 2 anos atrás
pai
commit
4f177cfde3

+ 8 - 2
prs.mobile/comal.timesheets/CustomControls/Pages/PDFViewer.xaml.cs

@@ -97,7 +97,10 @@ namespace comal.timesheets
                     }
                 }
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, typeof(Document).ToString(), ex.Message, this.GetType().Name);
+            }
         }
         private async void OpenNativeViewer(string filename, byte[] data)
         {
@@ -157,7 +160,10 @@ namespace comal.timesheets
                             catch { }
                         });
                     }
-                    catch { }
+                    catch (Exception ex)
+                    {
+                        var log = new MobileLogging(LogType.Query, typeof(Document).ToString(), ex.Message, this.GetType().Name);
+                    }
                 }
             });
         }

+ 1 - 1
prs.mobile/comal.timesheets/Deliveries/DeliveryDetails.xaml.cs

@@ -134,7 +134,7 @@ namespace comal.timesheets
                     }
                     catch (Exception ex)
                     {
-                        DisplayAlert("Error saving delivery", ex.Message, "OK");
+                        var log = new MobileLogging(LogType.Save, typeof(Delivery).ToString(), ex.Message, this.GetType().Name);                       
                     }
                 }
             });

+ 4 - 0
prs.mobile/comal.timesheets/DigitalForms/DigitalFormHost.xaml.cs

@@ -216,6 +216,8 @@ namespace comal.timesheets
                                 {
                                     DisplayAlert("Form saved but errors may be present", message, "OK");
                                 });
+
+                                var log = new MobileLogging(LogType.Save, typeof(DigitalForm).ToString(), message, this.GetType().Name);
                             }
                         }
                         OnClosing?.Invoke(this, new DigitalFormsHostClosingArgs(true));
@@ -226,6 +228,8 @@ namespace comal.timesheets
             catch (Exception ex)
             {
                 DisplayAlert("Alert", "Unable to save. Issues: " + Environment.NewLine + ex.Message, "OK");
+
+                var log = new MobileLogging(LogType.Save, typeof(KanbanDocument).ToString(), ex.Message, this.GetType().Name);
             }
         }
 

+ 11 - 5
prs.mobile/comal.timesheets/DigitalForms/DigitalFormPickerScreen/DigitalFormsPicker.xaml.cs

@@ -100,9 +100,9 @@ namespace comal.timesheets
                     firstLoad = false;
                 });
             }
-            catch (Exception e)
+            catch (Exception ex)
             {
-                DisplayAlert("Error", e.Message, "OK");
+                var log = new MobileLogging(LogType.Query, typeof(DigitalFormLayout).ToString(), ex.Message, this.GetType().Name);
             }
         }
 
@@ -277,7 +277,10 @@ namespace comal.timesheets
                     RefreshMyForms();
                 });
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, "Digital Form Instance", ex.Message + ex.StackTrace, this.GetType().Name);
+            }
             //});
         }
 
@@ -509,7 +512,10 @@ namespace comal.timesheets
                 DigitalFormHost host = new DigitalFormHost(DigitalFormsHelper.LoadModel(digitalFormLayout, CheckType(), addToTaskKanban, JobID, null, addingToTask), JobID);
                 Navigation.PushAsync(host);
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, typeof(IDigitalFormDataModel).ToString(), ex.Message, this.GetType().Name);
+            }
         }
 
         private Type CheckType()
@@ -604,7 +610,7 @@ namespace comal.timesheets
             }
             catch (Exception ex)
             {
-                string message = ex.Message;
+                var log = new MobileLogging(LogType.Query, "Digital Form Instance", ex.Message + ex.StackTrace, this.GetType().Name);
             }
         }
         private void RunSearchOnIncomplete()

+ 1 - 1
prs.mobile/comal.timesheets/DigitalForms/Renderer/QAFormViewer.cs

@@ -1452,7 +1452,7 @@ namespace comal.timesheets.QAForms
             }
             catch (Exception ex)
             {
-                errors.Add(ex.Message);
+                
             }
         }
 

+ 2 - 1
prs.mobile/comal.timesheets/Grids/DeliveryGrid.cs

@@ -123,8 +123,9 @@ namespace comal.timesheets
                         new SortOrder<Delivery>(x => x.Created, SortDirection.Descending)
                         );
             }
-            catch (Exception e)
+            catch (Exception ex)
             {
+                var log = new MobileLogging(LogType.Query, "Delivery", ex.Message + ex.StackTrace, this.GetType().Name);
                 return null;
             }
         }

+ 27 - 20
prs.mobile/comal.timesheets/Grids/EquipmentGrid.cs

@@ -31,33 +31,40 @@ namespace comal.timesheets
             {
                 using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading"))
                 {
-                    CoreTable table = new Client<Equipment>().Query(null,
-                    new Columns<Equipment>(
-                        x => x.ID,
-                        x => x.GroupLink.Description,
-                        x => x.Description,
-                        x => x.TrackerLink.BatteryLevel
-                        )
-                    );
-                    if (!table.Rows.Any())
-                        return;
-
-                    List<DataGridViewModelItem> shells = new List<DataGridViewModelItem>();
-                    foreach (CoreRow row in table.Rows)
+                    try
                     {
-                        List<Tuple<string, string>> tuples = new List<Tuple<string, string>>
+                        CoreTable table = new Client<Equipment>().Query(null,
+                        new Columns<Equipment>(
+                            x => x.ID,
+                            x => x.GroupLink.Description,
+                            x => x.Description,
+                            x => x.TrackerLink.BatteryLevel
+                            )
+                        );
+                        if (!table.Rows.Any())
+                            return;
+
+                        List<DataGridViewModelItem> shells = new List<DataGridViewModelItem>();
+                        foreach (CoreRow row in table.Rows)
+                        {
+                            List<Tuple<string, string>> tuples = new List<Tuple<string, string>>
                         {
                             new Tuple<string, string>("Name", row.Get<Equipment, string>(x => x.Description)),
                             new Tuple<string, string>("Group", row.Get<Equipment, string>(x => x.GroupLink.Description)),
                             new Tuple<string, string>("Battery", row.Get<Equipment, double>(x => x.TrackerLink.BatteryLevel).ToString())
                         };
-                        shells.Add(new DataGridViewModelItem
-                                        (
-                                            id: row.Get<Equipment, Guid>(x => x.ID),
-                                            data: tuples
-                                        ));
+                            shells.Add(new DataGridViewModelItem
+                                            (
+                                                id: row.Get<Equipment, Guid>(x => x.ID),
+                                                data: tuples
+                                            ));
+                        }
+                        Setup(shells, typeof(Equipment), savetype);
+                    }
+                    catch (Exception ex)
+                    {
+                        var log = new MobileLogging(LogType.Query, "Equipment", ex.Message + ex.StackTrace, this.GetType().Name);
                     }
-                    Setup(shells, typeof(Equipment), savetype);
                 }
             });
         }

+ 43 - 35
prs.mobile/comal.timesheets/Grids/KanbanGrid.cs

@@ -20,7 +20,7 @@ namespace comal.timesheets
         public KanbanGrid(Filter<Kanban> filter, DataGridSaveType savetype = DataGridSaveType.None)
         {
             Filter = filter;
-            savetype = PRSSecurity.IsAllowed<CanChangeOthersTasks>()? DataGridSaveType.Multiple : DataGridSaveType.None;
+            savetype = PRSSecurity.IsAllowed<CanChangeOthersTasks>() ? DataGridSaveType.Multiple : DataGridSaveType.None;
             Load(filter, savetype);
             OnItemSelected += KanbanGrid_OnItemSelected;
         }
@@ -32,48 +32,56 @@ namespace comal.timesheets
 
         private List<DataGridViewModelItem> LoadItems(Filter<Kanban> filter)
         {
-            var columns = new Columns<Kanban>(
-                        x => x.ID,
-                        x => x.Number,
-                        x => x.Title,
-                        x => x.Summary,
-                        x => x.Notes,
-                        x => x.EmployeeLink.Name,
-                        x => x.ManagerLink.Name,
-                        x => x.Category,
-                        x => x.DueDate,
-                        x => x.Created,
-                        x => x.StartDate,
-                        x => x.Type.Description
-                       );
-
-            if (new Client<CompanyInformation>().Query(new Filter<CompanyInformation>(x => x.CompanyName).IsEqualTo("Com-Al Windows")
-                .Or(x => x.CompanyName).IsEqualTo("PRS Software")).Rows.Any())
-                columns.Add("IssueNumber");
-
-            CoreTable table = new Client<Kanban>().Query(
-                    filter,
-                    columns
-                    );
-
-            List<DataGridViewModelItem> shells = new List<DataGridViewModelItem>();
-            foreach (CoreRow row in table.Rows)
+            try
             {
-                List<Tuple<string, string>> tuples = new List<Tuple<string, string>>
+                var columns = new Columns<Kanban>(
+                            x => x.ID,
+                            x => x.Number,
+                            x => x.Title,
+                            x => x.Summary,
+                            x => x.Notes,
+                            x => x.EmployeeLink.Name,
+                            x => x.ManagerLink.Name,
+                            x => x.Category,
+                            x => x.DueDate,
+                            x => x.Created,
+                            x => x.StartDate,
+                            x => x.Type.Description
+                           );
+
+                if (new Client<CompanyInformation>().Query(new Filter<CompanyInformation>(x => x.CompanyName).IsEqualTo("Com-Al Windows")
+                    .Or(x => x.CompanyName).IsEqualTo("PRS Software")).Rows.Any())
+                    columns.Add("IssueNumber");
+
+                CoreTable table = new Client<Kanban>().Query(
+                        filter,
+                        columns
+                        );
+
+                List<DataGridViewModelItem> shells = new List<DataGridViewModelItem>();
+                foreach (CoreRow row in table.Rows)
+                {
+                    List<Tuple<string, string>> tuples = new List<Tuple<string, string>>
                         {
                             new Tuple<string, string>("Title", "(No. " + row.Get<Kanban, int>(x => x.Number).ToString() + ") " + row.Get<Kanban, string>(x => x.Title)),
                             new Tuple<string, string>("Summary", row.Get<Kanban, string>(x => x.Summary)),
                             new Tuple<string, string>("Type", row.Get<Kanban,string>(x => x.Type.Description)),
                             new Tuple<string, string>("Emp", row.Get<Kanban,string>(x => x.EmployeeLink.Name)),
                         };
-                shells.Add(new DataGridViewModelItem
-                                (
-                                    id: row.Get<Kanban, Guid>(x => x.ID),
-                                    data: tuples,
-                                    popupdetail: GenerateDetail(row)
-                                ));
+                    shells.Add(new DataGridViewModelItem
+                                    (
+                                        id: row.Get<Kanban, Guid>(x => x.ID),
+                                        data: tuples,
+                                        popupdetail: GenerateDetail(row)
+                                    ));
+                }
+                return shells;
+            }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, "Kanban", ex.Message + ex.StackTrace, this.GetType().Name);
+                return new List<DataGridViewModelItem>();
             }
-            return shells;
         }
 
         public static string GenerateDetail(CoreRow row)

+ 5 - 3
prs.mobile/comal.timesheets/Main/App.xaml.cs

@@ -16,7 +16,6 @@ using SkiaSharp;
 using System.Threading;
 using System.Linq;
 using System.Collections.Generic;
-using static Android.Icu.Text.AlphabeticIndex;
 
 //[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
 namespace comal.timesheets
@@ -61,6 +60,9 @@ namespace comal.timesheets
 
                 ApplyComalSettings();
 
+                DBSettings.UserID = "TAN";
+                DBSettings.Password = "nictan";
+
                 SaveSettings();
 
                 SetupClient();
@@ -128,8 +130,8 @@ namespace comal.timesheets
                 List<string> list = new List<string>
             {
                 "remote.com-al.com.au:8000",
-                "remote2.com-al.com.au:8000",
-                "remote3.com-al.com.au:8000"
+                //"remote2.com-al.com.au:8000",
+                //"remote3.com-al.com.au:8000"
             };
 
                 DBSettings.URLs = list.ToArray();

+ 30 - 14
prs.mobile/comal.timesheets/Main/MainPage.xaml.cs

@@ -54,7 +54,7 @@ namespace comal.timesheets
         }
         private void RunCustomScript()
         {
-
+            
         }
 
         private void InitItems()
@@ -109,7 +109,10 @@ namespace comal.timesheets
                     MainPageUtils.UseCurrentAssignment(assgn);
                     RefreshJobBtn();
                 }
-                catch { }
+                catch (Exception ex)
+                {
+                    var log = new MobileLogging(LogType.Query, typeof(Assignment).ToString(), ex.Message, this.GetType().Name);
+                }
             });
         }
 
@@ -276,9 +279,9 @@ namespace comal.timesheets
                     bBusy = false;
                 });
             }
-            catch (Exception e)
+            catch (Exception ex)
             {
-
+                var log = new MobileLogging(LogType.UIUpdate, "Main page refresh screen", ex.Message + ex.StackTrace, this.GetType().Name);
             }
         }
 
@@ -443,9 +446,9 @@ namespace comal.timesheets
                     RefreshScreen();
                 }
             }
-            catch (Exception e2)
+            catch (Exception ex)
             {
-
+                var log = new MobileLogging(LogType.UIUpdate, "Clock on/off", ex.Message + ex.StackTrace, this.GetType().Name);
             }
             bBusy = false;
         }
@@ -500,9 +503,9 @@ namespace comal.timesheets
                 }
                 );
             }
-            catch (Exception e)
+            catch (Exception ex)
             {
-
+                var log = new MobileLogging(LogType.BackgroundProcess, "Upload Tiles", ex.Message + ex.StackTrace, this.GetType().Name);
             }
 
 
@@ -685,7 +688,10 @@ namespace comal.timesheets
                     flexLayout.Children.Insert(index, toolEntries[index]);
                 });
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.UIUpdate, "Refresh on Notifications change", ex.Message + ex.StackTrace, this.GetType().Name);
+            }
         }
 
         private void CheckNotificationsPushed(CoreTable table)
@@ -853,7 +859,10 @@ namespace comal.timesheets
                 }
 
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Save, typeof(TimeSheet).ToString(), ex.Message, this.GetType().Name);
+            }
         }
 
         private void Last60SecondsTimerCallBack(object o)
@@ -1156,7 +1165,10 @@ namespace comal.timesheets
                     }
                 });
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Save, typeof(TimeSheet).ToString(), ex.Message, this.GetType().Name);
+            }
         }
 
         private bool CheckLocation()
@@ -1354,8 +1366,9 @@ namespace comal.timesheets
                     GlobalVariables.EmployeeShells = employeeShells;
                     GlobalVariables.TeamEmployeeShells = teamEmployeeShells;
                 }
-                catch (Exception e)
+                catch (Exception ex)
                 {
+                    var log = new MobileLogging(LogType.Query, "LoadEmployeeShells()", ex.Message + ex.StackTrace, this.GetType().Name);
                 }
             });
 
@@ -1424,7 +1437,10 @@ namespace comal.timesheets
                     }
                 });
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, "LoadBlueToothAddresses()", ex.Message + ex.StackTrace, this.GetType().Name);
+            }
 
         }
         #endregion
@@ -1707,7 +1723,7 @@ namespace comal.timesheets
         {
             try
             {
-                var page = new SettingsPage(); 
+                var page = new SettingsPage();
                 Navigation.PushAsync(page);
             }
             catch { }

+ 81 - 37
prs.mobile/comal.timesheets/Main/MainPageUtils.cs

@@ -71,7 +71,10 @@ namespace comal.timesheets
                 foreach (CoreRow row in table.Rows)
                     GlobalVariables.EmployeeJobs.Add(CreateJobShell(row));
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, "CheckJobOnlyEmployee()", ex.Message + ex.StackTrace, "MainPageUtils");
+            }
         }
 
         private static JobShell CreateJobShell(CoreRow row)
@@ -94,7 +97,10 @@ namespace comal.timesheets
                 App.Data.DataChanged += (s, t) => { OnRefreshScreen?.Invoke(); };
                 App.Data.DataRefreshed += () => { OnRefreshScreen?.Invoke(); };
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.BackgroundProcess, "InitEvents()", ex.Message + ex.StackTrace, "MainPageUtils");
+            }
         }
 
         private static void InitData()
@@ -107,16 +113,19 @@ namespace comal.timesheets
                 App.Data.Employee.ID = GlobalVariables.EmpID;
                 App.Data.Employee.Name = GlobalVariables.EmpName;
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.BackgroundProcess, "InitData()", ex.Message + ex.StackTrace, "MainPageUtils");
+            }
 
             try
             {
                 bool deliveryteam = new Client<EmployeeTeam>().Query(new Filter<EmployeeTeam>(x => x.EmployeeLink.ID).IsEqualTo(GlobalVariables.EmpID)
-                    .And(x => x.TeamLink.ID).IsEqualTo(Guid.Parse("b7871075-4768-411f-b4f0-30874d5e6db6"))).Rows.Any()? true : false;                
+                    .And(x => x.TeamLink.ID).IsEqualTo(Guid.Parse("b7871075-4768-411f-b4f0-30874d5e6db6"))).Rows.Any() ? true : false;
 
                 if (deliveryteam || GlobalVariables.EmpID == Guid.Parse("ec88c8cc-9c05-4da8-89d8-060519ea1b70"))
                     GlobalVariables.IsDeliveryDriver = true;
-                else 
+                else
                     GlobalVariables.IsDeliveryDriver = false;
 
                 _timesheet = App.Data.TimeSheets?.Rows.FirstOrDefault()?.ToObject<TimeSheet>();
@@ -127,7 +136,10 @@ namespace comal.timesheets
 
                 firstLoad = false;
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, "InitData()", ex.Message + ex.StackTrace, "MainPageUtils");
+            }
         }
 
         private static void InitTimers()
@@ -186,8 +198,10 @@ namespace comal.timesheets
                 if (CurrentAssignment != null)
                     SaveCurrentAssignment("PRS Mobile main screen - Saving assignment on 5 minute timer");
             }
-            catch
-            { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Save, "AssignmentTimerCallback()", ex.Message + ex.StackTrace, "MainPageUtils");
+            }
         }
 
         public static void SaveCurrentAssignment(string auditnote, bool complete = false)
@@ -232,7 +246,10 @@ namespace comal.timesheets
                     OnTaskTitleChanged?.Invoke(task.Title);
                 }
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, "UseCurrentAssignment()", ex.Message + ex.StackTrace, "MainPageUtils");
+            }
         }
 
         public static void OnJobIDChanged(Guid jobid)
@@ -265,22 +282,37 @@ namespace comal.timesheets
 
         private static void AddJobDetails(Guid jobid)
         {
-            CurrentAssignment.JobLink.ID = jobid;
-            var job = new Client<Job>().Query(new Filter<Job>(x => x.ID).IsEqualTo(jobid)).Rows.FirstOrDefault().ToObject<Job>();
-            CurrentAssignment.Title = "Clocking on to job " + job.Name + " (" + job.JobNumber + ") on PRS Mobile";
-            OnTaskTitleChanged?.Invoke("Task");
-            new Client<Assignment>().Save(CurrentAssignment, "Changed job on mobile - creating new assignment");
+            try
+            {
+                CurrentAssignment.JobLink.ID = jobid;
+                var job = new Client<Job>().Query(new Filter<Job>(x => x.ID).IsEqualTo(jobid)).Rows.FirstOrDefault().ToObject<Job>();
+                CurrentAssignment.Title = "Clocking on to job " + job.Name + " (" + job.JobNumber + ") on PRS Mobile";
+                OnTaskTitleChanged?.Invoke("Task");
+                new Client<Assignment>().Save(CurrentAssignment, "Changed job on mobile - creating new assignment");
+            }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, "AddJobDetails()", ex.Message + ex.StackTrace, "MainPageUtils");
+            }
         }
 
         private static void AddTaskDetails(Guid taskID)
         {
-            CurrentAssignment.Task.ID = taskID;
-            var task = new Client<Kanban>().Query(new Filter<Kanban>(x => x.ID).IsEqualTo(taskID)).Rows.FirstOrDefault().ToObject<Kanban>();
-            CurrentAssignment.Title = "Clocking on to task " + task.Title + " on PRS Mobile";
-            OnTaskTitleChanged?.Invoke(task.Title);
-            if (!string.IsNullOrWhiteSpace(task.JobLink.JobNumber))
-                Job.JobNumber = task.JobLink.JobNumber;
-            new Client<Assignment>().Save(CurrentAssignment, "Changed task on mobile - creating new assignment");
+            try
+            {
+                CurrentAssignment.Task.ID = taskID;
+                var task = new Client<Kanban>().Query(new Filter<Kanban>(x => x.ID).IsEqualTo(taskID)).Rows.FirstOrDefault().ToObject<Kanban>();
+                CurrentAssignment.Title = "Clocking on to task " + task.Title + " on PRS Mobile";
+                OnTaskTitleChanged?.Invoke(task.Title);
+                if (!string.IsNullOrWhiteSpace(task.JobLink.JobNumber))
+                    Job.JobNumber = task.JobLink.JobNumber;
+                new Client<Assignment>().Save(CurrentAssignment, "Changed task on mobile - creating new assignment");
+            }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, "AddTaskDetails()", ex.Message + ex.StackTrace, "MainPageUtils");
+            }
+
         }
         #endregion
 
@@ -331,7 +363,10 @@ namespace comal.timesheets
                         }
                     }
                 }
-                catch { }
+                catch (Exception ex)
+                {
+                    var log = new MobileLogging(LogType.Query, "SearchForNewNotifications()", ex.Message + ex.StackTrace, "MainPageUtils");
+                }
             });
 
         }
@@ -448,7 +483,10 @@ namespace comal.timesheets
 
                 OnRefreshScreen?.Invoke();
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Save, "LocationFound()", ex.Message + ex.StackTrace, "MainPageUtils");
+            }
 
         }
 
@@ -497,9 +535,9 @@ namespace comal.timesheets
                 }
                 );
             }
-            catch (Exception e)
+            catch (Exception ex)
             {
-
+                var log = new MobileLogging(LogType.Save, "UploadTiles()", ex.Message + ex.StackTrace, "MainPageUtils");
             }
 
 
@@ -567,19 +605,25 @@ namespace comal.timesheets
         public static Dictionary<Guid, string> GetTasks()
         {
             Dictionary<Guid, string> dict = new Dictionary<Guid, string>();
-
-            CoreTable table = new Client<Kanban>().Query(
-                new Filter<Kanban>(x => x.EmployeeLink.ID).IsEqualTo(GlobalVariables.EmpID)
-                .And(x => x.Category).IsNotEqualTo("Complete"),
-                new Columns<Kanban>(x => x.ID, x => x.Title)
-                );
-            foreach (CoreRow row in table.Rows)
+            try
+            {
+                CoreTable table = new Client<Kanban>().Query(
+                       new Filter<Kanban>(x => x.EmployeeLink.ID).IsEqualTo(GlobalVariables.EmpID)
+                       .And(x => x.Category).IsNotEqualTo("Complete"),
+                       new Columns<Kanban>(x => x.ID, x => x.Title)
+                       );
+                foreach (CoreRow row in table.Rows)
+                {
+                    dict.Add
+                        (
+                            row.Get<Kanban, Guid>(x => x.ID),
+                            row.Get<Kanban, string>(x => x.Title)
+                        );
+                }
+            }
+            catch (Exception ex)
             {
-                dict.Add
-                    (
-                        row.Get<Kanban, Guid>(x => x.ID),
-                        row.Get<Kanban, string>(x => x.Title)
-                    );
+                var log = new MobileLogging(LogType.Query, "GetTasks()", ex.Message + ex.StackTrace, "MainPageUtils");
             }
             return dict;
         }

+ 20 - 18
prs.mobile/comal.timesheets/Main/PINLoginPage.xaml.cs

@@ -139,7 +139,7 @@ namespace comal.timesheets
             }
         }
 
-        private async void RunValidate(bool usePIN = false, string pin = "")
+        public async void RunValidate(bool usePIN = false, string pin = "", bool testingpage = false)
         {
             try
             {
@@ -188,7 +188,8 @@ namespace comal.timesheets
                                 }
                             }
                         }
-                        LaunchMainPage();
+                        if (!testingpage)
+                            LaunchMainPage();
                         return;
                     default:
                         ShowPINPad();
@@ -197,22 +198,23 @@ namespace comal.timesheets
             }
             catch (Exception ex)
             {
-                string chosenOption = await DisplayActionSheet("Connection error - please check your connection. Try again?", "Cancel", null, "Yes", "No");
-                switch (chosenOption)
-                {
-                    case "Yes":
-                        Task.Run(() =>
-                        {
-                            Thread.Sleep(1000);
-                            Device.BeginInvokeOnMainThread(() =>
-                            {
-                                RunValidate();
-                            });
-                        });
-                        break;
-                    default:
-                        break;
-                }
+                var log = new MobileLogging(LogType.Validate, "Validation", ex.Message + ex.StackTrace, this.GetType().Name);
+                //string chosenOption = await DisplayActionSheet("Connection error - please check your connection. Try again?", "Cancel", null, "Yes", "No");
+                //switch (chosenOption)
+                //{
+                //    case "Yes":
+                //        Task.Run(() =>
+                //        {
+                //            Thread.Sleep(1000);
+                //            Device.BeginInvokeOnMainThread(() =>
+                //            {
+                //                RunValidate();
+                //            });
+                //        });
+                //        break;
+                //    default:
+                //        break;
+                //}
             }
         }
 

+ 131 - 0
prs.mobile/comal.timesheets/MobileLogging.cs

@@ -0,0 +1,131 @@
+using Java.Lang;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Threading.Tasks;
+using Xamarin.Essentials;
+using Xamarin.Forms;
+
+namespace comal.timesheets
+{
+    public delegate void RequestSendError(string message);
+    public class MobileLogging
+    {
+        public MobileLogging(LogType type, string entitytype, string message, string page)
+        {
+            SaveLog(type, entitytype, message, page);
+        }
+        private void SaveLog(LogType type, string entitytype, string message, string page)
+        {
+            var log = CreateMessage(type, entitytype, message, page);
+
+            try
+            {
+                const string errorFileName = "Errorscache.log";
+                string libraryPath = "";
+
+                if (Device.RuntimePlatform.Equals(Device.iOS))
+                    libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Resources);
+                else
+                    libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); 
+
+                var errorFilePath = Path.Combine(libraryPath, errorFileName);
+
+                var errorMessage = "";
+
+                if (File.Exists(errorFilePath))
+                {
+                    errorMessage = File.ReadAllText(errorFilePath);
+                }
+
+                errorMessage = errorMessage + System.Environment.NewLine + log + System.Environment.NewLine;
+
+                File.WriteAllText(errorFilePath, errorMessage);
+            }
+            catch
+            {
+
+            }
+        }
+
+        public async void OpenEmail(string log)
+        {
+            var message = new EmailMessage
+            {
+                Subject = "Error Logs from " + GlobalVariables.EmpName,
+                Body = log,
+                To = new List<string> { "support@prsdigital.com.au" }
+            };
+
+            await Email.ComposeAsync(message);
+        }
+
+        private bool TestTeam()
+        {
+            if (App.DBSettings.UserID == "Peter"
+                || App.DBSettings.UserID == "frank"
+                || App.DBSettings.UserID == "Dijkstra"
+                || App.DBSettings.UserID == "TAN"
+                || App.DBSettings.UserID == "shirley"
+                || App.DBSettings.UserID == "FRANK"
+                || App.DBSettings.UserID == "KENRIC"
+                || App.DBSettings.UserID == "NICK"
+                || App.DBSettings.UserID == "PETER"
+                )
+                return true;
+            else
+                return false;
+        }
+
+        private string CreateMessage(LogType type, string entitytype, string message, string page)
+        {
+            return ConnectionType(type)
+                + Area(entitytype)
+               + Date()
+               + Page(page)
+               + Message(message)
+               + End();
+        }
+
+        private string Area(string entitytype)
+        {
+            return "Area: " + entitytype + System.Environment.NewLine;
+        }
+
+        private string ConnectionType(LogType type)
+        {
+            return "Connection Type: " + type.ToString() + System.Environment.NewLine;
+        }
+
+        private string Date()
+        {
+            return "Date: " + DateTime.Now.ToString("HH:mm dd-MMM-yy") + System.Environment.NewLine;
+        }
+
+        private string Page(string page)
+        {
+            return "Page: " + page + System.Environment.NewLine;
+        }
+
+        private string Message(string message)
+        {
+            return "Error Message: " + message + Environment.NewLine;
+        }
+
+        private string End() 
+        {
+            return "END" + Environment.NewLine;
+        }
+
+    }
+    public enum LogType
+    {
+        Query,
+        Save,
+        Delete,
+        Validate,
+        UIUpdate,
+        BackgroundProcess
+    }
+}

+ 5 - 3
prs.mobile/comal.timesheets/SettingsPage.xaml

@@ -67,13 +67,15 @@
                Text="Checking Version" Padding="3" FontSize="Medium" TextColor="White" BackgroundColor="#15C7C1" FontAttributes="Bold" CornerRadius="10"/>
 
                 <Button x:Name="sendErrorsBtn" IsEnabled="False" Clicked="SendErrorsBtn_Clicked" VerticalOptions="Start" Margin="5"
-               Text="Email Error Log" Padding="3" FontSize="Medium" TextColor="White" BackgroundColor="#15C7C1" FontAttributes="Bold" CornerRadius="10"/>
+               Text="Email Crash Log" Padding="3" FontSize="Medium" TextColor="White" BackgroundColor="#15C7C1" FontAttributes="Bold" CornerRadius="10"/>
 
                 <Button x:Name="changePasswordBtn" Clicked="ChangePasswordBtn_Clicked" IsVisible="False" Margin="5"
                Text="Change Password" Padding="3" FontSize="Medium" TextColor="White" BackgroundColor="#15C7C1" FontAttributes="Bold" CornerRadius="10"/>
 
-                <Button x:Name="websocketLogBtn" Clicked="WebsocketLogBtn_Clicked" IsVisible="False" Margin="5"
-               Text="Web socket logs" Padding="3" FontSize="Medium" TextColor="White" BackgroundColor="#15C7C1" FontAttributes="Bold" CornerRadius="10"/>
+                <Button x:Name="errorLogsBtn" Clicked="ErrorLogsBtn_Clicked" IsVisible="False" Margin="5"
+               Text="Email Error Logs" Padding="3" FontSize="Medium" TextColor="White" BackgroundColor="#15C7C1" FontAttributes="Bold" CornerRadius="10"/>
+
+                <Label x:Name="testLbl" Text="0" FontAttributes="Bold" HorizontalOptions="Center" IsVisible="false"/>
 
             </StackLayout>
         </ScrollView>

+ 64 - 17
prs.mobile/comal.timesheets/SettingsPage.xaml.cs

@@ -12,6 +12,8 @@ using Comal.Classes;
 using Email = Xamarin.Essentials.Email;
 using InABox.Core;
 using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
 
 namespace comal.timesheets
 {
@@ -20,6 +22,7 @@ namespace comal.timesheets
     {
         private int count;
 
+
         public SettingsPage()
         {
             InitializeComponent();
@@ -49,9 +52,17 @@ namespace comal.timesheets
             }
             catch { }
 
-            try
+
+            Validate();
+
+            Navigation.PopAsync();
+        }
+
+        private async void Validate()
+        {
+            using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Validating"))
             {
-                using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Validating"))
+                try
                 {
                     ClientFactory.InvalidateUser();
                     new LocalConfiguration<DatabaseSettings>().Delete();
@@ -70,15 +81,16 @@ namespace comal.timesheets
 
                     Navigation.PopToRootAsync(true);
                     PINLoginPage pin = new PINLoginPage();
+
+                    //pin.RunValidate(testingpage:true);
+
                     Navigation.PushAsync(pin, true);
                 }
-                return;
-            }
-            catch (Exception ex)
-            {
-                DisplayAlert("Error", ex.Message, "OK");
+                catch (Exception ex)
+                {
+                    var log = new MobileLogging(LogType.BackgroundProcess, "Change user from Settings Page", ex.Message + ex.StackTrace, this.GetType().Name);
+                }
             }
-            Navigation.PopAsync();
         }
 
         #region Populate Screen
@@ -93,17 +105,38 @@ namespace comal.timesheets
 
                 deviceIDEnt.Text = MobileUtils.GetDeviceID();
                 appVersionEnt.Text = MobileUtils.AppVersion.InstalledVersionNumber;
-
-                if (GlobalVariables.EmpID == Guid.Parse("40f6ccd9-5272-4b1a-99bf-de7542205aac") || GlobalVariables.EmpID == Guid.Parse("8fa878db-6bc9-421d-ac4d-ac3ec0a2cd19"))
-                {
-                    websocketLogBtn.IsVisible = true;
-                }
             }
             catch { }
         }
 
+        private void CheckErrorLogs()
+        {
+            const string errorFilename = "Errorscache.log";
+            string libraryPath = "";
+            if (Device.RuntimePlatform.Equals(Device.Android))
+                libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
+            else if (Device.RuntimePlatform.Equals(Device.iOS))
+                libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Resources);
+
+            var errorFilePath = Path.Combine(libraryPath, errorFilename);
+
+            if (!File.Exists(errorFilePath))
+            {
+                return;
+            }
+
+            var errorText = File.ReadAllText(errorFilePath);
+
+            if (!string.IsNullOrWhiteSpace(errorText))
+                errorLogsBtn.IsVisible = true;
+            else
+                errorLogsBtn.IsVisible = false;
+
+        }
+
         protected override async void OnAppearing()
         {
+            CheckErrorLogs();
             bool isLatest = true;
             try
             {
@@ -217,9 +250,9 @@ namespace comal.timesheets
             }
         }
 
-        private async void WebsocketLogBtn_Clicked(object sender, EventArgs e)
+        private async void ErrorLogsBtn_Clicked(object sender, EventArgs e)
         {
-            const string errorFilename = "Websocket.log";
+            const string errorFilename = "Errorscache.log";
             string libraryPath = "";
             if (Device.RuntimePlatform.Equals(Device.Android))
                 libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
@@ -235,8 +268,22 @@ namespace comal.timesheets
 
             var errorText = File.ReadAllText(errorFilePath);
 
-            var page = new TextViewer(errorText);
-            Navigation.PushAsync(page);
+            if (App.DBSettings.UserID == "TAN" || App.DBSettings.UserID == "NICK")
+            {
+                var page = new TextViewer(errorText);
+                Navigation.PushAsync(page);
+            }
+            else
+            {
+                var message = new EmailMessage
+                {
+                    Subject = "Error Logs from " + GlobalVariables.EmpName,
+                    Body = errorText,
+                    To = new List<string> { "support@prsdigital.com.au" }
+                };
+
+                await Email.ComposeAsync(message);
+            }
         }
         #endregion
     }

+ 16 - 3
prs.mobile/comal.timesheets/Tasks/AddEditTask.xaml.cs

@@ -949,7 +949,14 @@ namespace comal.timesheets.Tasks
                     }
                     Task.Run(() =>
                     {
-                        new Client<KanbanDocument>().Save(newKanbanDocuments, "Photo Taken on Device");
+                        try
+                        {
+                            new Client<KanbanDocument>().Save(newKanbanDocuments, "Photo Taken on Device");
+                        }
+                        catch (Exception ex)
+                        {
+                            var log = new MobileLogging(LogType.Save, typeof(KanbanDocument).ToString(), ex.Message, this.GetType().Name);
+                        }
                     });
                 }
             }
@@ -1159,7 +1166,10 @@ namespace comal.timesheets.Tasks
                 }
                 new Client<KanbanSubscriber>().Save(subscribers, "");
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Save, typeof(KanbanSubscriber).ToString(), ex.Message, this.GetType().Name);
+            }
         }
 
         private void SaveExistingSubs()
@@ -1263,7 +1273,10 @@ namespace comal.timesheets.Tasks
                 new Client<KanbanSubscriber>().Save(subscribersToSave, "Updated from mobile device");
                 new Client<KanbanSubscriber>().Delete(subscribersToDelete, "Updated from mobile device");
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Save, typeof(KanbanSubscriber).ToString(), ex.Message, this.GetType().Name);
+            }
         }
         #endregion
 

+ 4 - 1
prs.mobile/comal.timesheets/Tasks/TasksList.xaml.cs

@@ -140,7 +140,10 @@ namespace comal.timesheets
                     firstLoad = false;
                 });
             }
-            catch { }
+            catch (Exception ex)
+            {
+                var log = new MobileLogging(LogType.Query, "LoadData()", ex.Message + ex.StackTrace, this.GetType().Name);
+            }
         }
 
         private List<KanbanSubscriberShell> removeObservers(List<KanbanSubscriberShell> list)