MainPageUtils.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Threading;
  5. using System.Threading.Tasks;
  6. using Xamarin.Forms;
  7. using InABox.Core;
  8. using InABox.Configuration;
  9. using InABox.Clients;
  10. using InABox.Mobile;
  11. using Comal.Classes;
  12. using XF.Material.Forms.UI.Dialogs;
  13. using comal.timesheets.CustomControls;
  14. using comal.timesheets.StoreRequis;
  15. using PRSSecurity = InABox.Core.Security;
  16. using Plugin.LocalNotification;
  17. using comal.timesheets.Tasks;
  18. using System.IO;
  19. using static comal.timesheets.CustomControls.JobShell;
  20. using static Android.Graphics.Paint;
  21. namespace comal.timesheets
  22. {
  23. public delegate void MainPageNotificationsChanged();
  24. public static class MainPageUtils
  25. {
  26. public static Assignment CurrentAssignment = null;
  27. public static JobShell Job = new JobShell();
  28. public static int NumberOfNotifications = 0;
  29. public static event MainPageNotificationsChanged OnMainPageNotificationsChanged;
  30. public static Assignment CheckCurrentAssignment()
  31. {
  32. Thread.Sleep(5000);
  33. StartAssignmentTimer();
  34. CoreTable table = new Client<Assignment>().Query(
  35. new Filter<Assignment>(x => x.EmployeeLink.ID).IsEqualTo(GlobalVariables.EmpID)
  36. .And(x => x.Date).IsEqualTo(DateTime.Today.Date)
  37. .And(x => x.Actual.Finish).IsEqualTo(null),
  38. null,
  39. new SortOrder<Assignment>(x => x.Actual.Start, SortDirection.Ascending));
  40. if (!table.Rows.Any())
  41. {
  42. Job.OnJobIDChanged += OnJobIDChanged;
  43. return null;
  44. }
  45. else
  46. return table.Rows.LastOrDefault().ToObject<Assignment>();
  47. }
  48. private static void StartAssignmentTimer()
  49. {
  50. Timer t = new Timer(AssignmentTimerCallback, null, 300000, 300000);
  51. }
  52. private static void AssignmentTimerCallback(object state)
  53. {
  54. if (CurrentAssignment != null)
  55. SaveCurrentAssignment("PRS Mobile main screen - Saving assignment on 5 minute timer");
  56. }
  57. public static void SaveCurrentAssignment(string auditnote, bool complete = false)
  58. {
  59. if (!complete)
  60. CurrentAssignment.Booked.Finish = RoundToNearestInterval(DateTime.Now, new TimeSpan(0, 5, 0)).TimeOfDay;
  61. else
  62. CurrentAssignment.Actual.Finish = RoundToNearestInterval(DateTime.Now, new TimeSpan(0, 5, 0)).TimeOfDay;
  63. new Client<Assignment>().Save(CurrentAssignment, auditnote);
  64. }
  65. static DateTime RoundToNearestInterval(DateTime dt, TimeSpan d)
  66. {
  67. int f = 0;
  68. double m = (double)(dt.Ticks % d.Ticks) / d.Ticks;
  69. if (m >= 0.5)
  70. f = 1;
  71. return new DateTime(((dt.Ticks / d.Ticks) + f) * d.Ticks);
  72. }
  73. public static void UseCurrentAssignment(Assignment assgn)
  74. {
  75. CurrentAssignment = assgn;
  76. SaveCurrentAssignment("PRS Mobile main screen - saving assignment on re-login to App");
  77. if (CurrentAssignment.JobLink.ID != Guid.Empty)
  78. {
  79. Job.ID = CurrentAssignment.JobLink.ID;
  80. var job = new Client<Job>().Query(new Filter<Job>(x => x.ID).IsEqualTo(Job.ID)).Rows.FirstOrDefault().ToObject<Job>();
  81. Job.JobNumber = job.JobNumber;
  82. Job.Name = job.Name;
  83. Job.OnJobIDChanged += OnJobIDChanged;
  84. }
  85. }
  86. public static void OnJobIDChanged(Guid jobid)
  87. {
  88. if (CurrentAssignment == null)
  89. CreateNewAssignment(jobid);
  90. else
  91. {
  92. SaveCurrentAssignment("PRS Mobile main screen - saving assignment on job change", true);
  93. CreateNewAssignment(jobid);
  94. }
  95. }
  96. private static void CreateNewAssignment(Guid jobid)
  97. {
  98. CurrentAssignment = new Assignment { Date = DateTime.Now.Date };
  99. CurrentAssignment.EmployeeLink.ID = GlobalVariables.EmpID;
  100. CurrentAssignment.JobLink.ID = jobid;
  101. CurrentAssignment.Actual.Start = RoundToNearestInterval(DateTime.Now, new TimeSpan(0, 5, 0)).TimeOfDay;
  102. CurrentAssignment.Booked.Start = CurrentAssignment.Actual.Start;
  103. CurrentAssignment.Booked.Finish = RoundToNearestInterval(DateTime.Now, new TimeSpan(0, 5, 0)).TimeOfDay.Add(new TimeSpan(0, 5, 0));
  104. var job = new Client<Job>().Query(new Filter<Job>(x => x.ID).IsEqualTo(jobid)).Rows.FirstOrDefault().ToObject<Job>();
  105. CurrentAssignment.Title = "Clocking on to job " + job.Name + " (" + job.JobNumber + ") on PRS Mobile";
  106. new Client<Assignment>().Save(CurrentAssignment, "Changed job on mobile - creating new assignment");
  107. }
  108. #region Notifications
  109. public static Page DetermineCorrectPage(Plugin.LocalNotification.EventArgs.NotificationActionEventArgs e)
  110. {
  111. string data = e.Request.ReturningData;
  112. int index = data.IndexOf("$");
  113. Guid ID = Guid.Parse(data.Remove(index));
  114. string type = data.Substring(index + 1);
  115. if (type == "Comal.Classes.Kanban")
  116. return new AddEditTask(ID);
  117. else if (type == "Comal.Classes.Delivery")
  118. return new DeliveryDetails(ID);
  119. else
  120. return null;
  121. }
  122. public static async void SearchForNewNotifications()
  123. {
  124. //notifications poll reliably in the background for Anroid, unreliable for iOS due to difficulty with cross-platform plugins for notifications
  125. try
  126. {
  127. await Task.Run(() =>
  128. {
  129. if (ClientFactory.UserGuid != Guid.Empty)
  130. {
  131. CoreTable table = new Client<Notification>().Query
  132. (new Filter<Notification>(x => x.Employee.UserLink.ID).IsEqualTo(ClientFactory.UserGuid).And(X => X.Closed).IsEqualTo(DateTime.MinValue),
  133. new Columns<Notification>(
  134. x => x.ID, //0
  135. x => x.Sender.Name, //1
  136. x => x.Title, //2
  137. x => x.Created, //3
  138. x => x.Description, //4
  139. x => x.EntityType, //5
  140. x => x.EntityID //6
  141. )
  142. );
  143. if (NumberOfNotifications == table.Rows.Count()) //no new notifications or none present at all
  144. return;
  145. else //new notifications or previous notifications have now been dismissed
  146. {
  147. NumberOfNotifications = table.Rows.Count();
  148. OnMainPageNotificationsChanged?.Invoke();
  149. CheckNotificationsPushed(table);
  150. }
  151. }
  152. });
  153. }
  154. catch { }
  155. }
  156. private static void CheckNotificationsPushed(CoreTable table)
  157. {
  158. try
  159. {
  160. if (!Application.Current.Properties.ContainsKey("LastPushedNotifications"))
  161. {
  162. Application.Current.Properties.Add("LastPushedNotifications", DateTime.Now);
  163. }
  164. DateTime lastPushed = DateTime.Parse(Application.Current.Properties["LastPushedNotifications"].ToString());
  165. List<NotificationShell> toNotify = new List<NotificationShell>();
  166. foreach (CoreRow row in table.Rows)
  167. {
  168. List<object> list = row.Values;
  169. DateTime created = DateTime.Parse(list[3].ToString());
  170. if (created > new DateTime(2022, 8, 22)) // prevent spam from buildup of old notifications before this is released
  171. {
  172. if (created > lastPushed)
  173. {
  174. if (list[1] == null) list[1] = "";
  175. if (list[2] == null) list[2] = "";
  176. if (list[3] == null) list[3] = DateTime.MinValue;
  177. if (list[4] == null) list[4] = "";
  178. if (list[5] == null) list[5] = "";
  179. if (list[6] == null) list[6] = Guid.Empty;
  180. NotificationShell shell = new NotificationShell
  181. {
  182. ID = Guid.Parse(list[0].ToString()),
  183. Sender = list[1].ToString(),
  184. Title = list[2].ToString(),
  185. Created = DateTime.Parse(list[3].ToString()),
  186. EntityType = list[5].ToString(),
  187. EntityID = Guid.Parse(list[6].ToString())
  188. };
  189. toNotify.Add(shell); //add notification to be pushed
  190. }
  191. }
  192. }
  193. if (toNotify.Count > 0)
  194. PushNotificationsAsync(toNotify);
  195. }
  196. catch { }
  197. }
  198. private static async Task PushNotificationsAsync(List<NotificationShell> shells)
  199. {
  200. try
  201. {
  202. int count = 1;
  203. foreach (NotificationShell shell in shells)
  204. {
  205. var notification = new NotificationRequest
  206. {
  207. BadgeNumber = 1,
  208. Description = shell.Title,
  209. Title = "New PRS Notification: ",
  210. ReturningData = shell.EntityID.ToString() + "$" + shell.EntityType,
  211. NotificationId = count,
  212. };
  213. count++;
  214. NotificationImage img = new NotificationImage();
  215. img.ResourceName = "icon16.png";
  216. notification.Image = img;
  217. await LocalNotificationCenter.Current.Show(notification);
  218. }
  219. Application.Current.Properties["LastPushedNotifications"] = DateTime.Now;
  220. }
  221. catch { }
  222. }
  223. #endregion
  224. }
  225. }