DeliveryList.xaml.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. using Xamarin.Forms;
  5. using InABox.Core;
  6. using InABox.Clients;
  7. using Comal.Classes;
  8. using XF.Material.Forms.UI;
  9. using XF.Material.Forms.UI.Dialogs;
  10. using System.Linq;
  11. using comal.timesheets.Deliveries;
  12. using System.Threading;
  13. using System.IO;
  14. using System.Linq.Expressions;
  15. using InABox.Configuration;
  16. using Xamarin.Essentials;
  17. namespace comal.timesheets
  18. {
  19. public class DeliveryModuleSettings : ILocalConfigurationSettings
  20. {
  21. public int CurrentSearch { get; set; }
  22. }
  23. public partial class DeliveryList
  24. {
  25. private Tuple<String, Func<DeliveryShell, bool>>[] _searches = new Tuple<string, Func<DeliveryShell, bool>>[]
  26. {
  27. new Tuple<String, Func<DeliveryShell, bool>>("Today's Deliveries", (shell) => shell.Date == DateTime.Today),
  28. new Tuple<String, Func<DeliveryShell, bool>>("Last 7 Days",
  29. (shell) => shell.Delivered > DateTime.Today.AddDays(-7)),
  30. new Tuple<String, Func<DeliveryShell, bool>>("Last 30 Days",
  31. (shell) => shell.Delivered > DateTime.Today.AddDays(-30)),
  32. new Tuple<String, Func<DeliveryShell, bool>>("Future Deliveries", (shell) => shell.Delivered.IsEmpty())
  33. };
  34. private String _currentfilter = "";
  35. private DeliveryModuleSettings _settings;
  36. public DeliveryList()
  37. {
  38. _settings = new LocalConfiguration<DeliveryModuleSettings>().Load();
  39. InitializeComponent();
  40. RefreshData(false, true);
  41. }
  42. private void RefreshData(bool force, bool async)
  43. {
  44. if (async)
  45. {
  46. App.Data.Deliveries.Refresh(force, Refresh);
  47. }
  48. else
  49. {
  50. App.Data.Deliveries.Refresh(true);
  51. Refresh();
  52. }
  53. }
  54. private void Refresh()
  55. {
  56. App.Data.Deliveries.Search((shell) =>
  57. _searches[_settings.CurrentSearch].Item2(shell) && FilterShell(shell));
  58. _deliveries.ItemsSource = App.Data.Deliveries.Items;
  59. }
  60. private bool FilterShell(DeliveryShell shell)
  61. {
  62. if (String.IsNullOrWhiteSpace(_currentfilter))
  63. return true;
  64. return shell.Address.ToUpper().Contains(_currentfilter.ToUpper())
  65. || shell.Job.ToUpper().Contains(_currentfilter.ToUpper())
  66. || shell.Number.ToString().Contains(_currentfilter.ToUpper());
  67. }
  68. private void MobileList_OnRefresh(object sender, MobileListRefreshEventArgs args)
  69. {
  70. RefreshData(true, false);
  71. }
  72. private async void _filter_OnClicked(object sender, EventArgs e)
  73. {
  74. var view = new MaterialRadioButtonGroup()
  75. {
  76. Choices = _searches.Select(x => x.Item1).ToList(),
  77. SelectedIndex = _settings.CurrentSearch
  78. };
  79. bool? wasConfirmed =
  80. await MaterialDialog.Instance.ShowCustomContentAsync(view, "Select deliveries to display",
  81. "Filter List");
  82. if (wasConfirmed == true)
  83. {
  84. _settings.CurrentSearch = view.SelectedIndex;
  85. new LocalConfiguration<DeliveryModuleSettings>().Save(_settings);
  86. Refresh();
  87. }
  88. }
  89. private void _search_OnTextChanged(object sender, MobileSearchBarTextChangedArgs args)
  90. {
  91. _currentfilter = args.Text;
  92. Refresh();
  93. }
  94. private async void Deliveries_OnItemTapped(object sender, MobileListItemTappedEventArgs args)
  95. {
  96. await MaterialDialog.Instance.AlertAsync("Not Implemented Yet!");
  97. return;
  98. // if (sender is DeliveryShell shell)
  99. // {
  100. // DeliveryDetails page = new DeliveryDetails() { DeliveryID = shell.ID };
  101. // Navigation.PushAsync(page);
  102. // }
  103. }
  104. private async void AddDelivery_Clicked(object sender, EventArgs e)
  105. {
  106. await MaterialDialog.Instance.AlertAsync("Not Implemented Yet!");
  107. // Delivery delivery = new Delivery();
  108. // var details = new DeliveryDetails(delivery.ID);
  109. // Navigation.PushAsync(details);
  110. }
  111. /*
  112. private async void Load()
  113. {
  114. Title = "Refreshing";
  115. await Task.Run(() =>
  116. {
  117. LoadData();
  118. Device.BeginInvokeOnMainThread(async () =>
  119. {
  120. AdjustOpenList();
  121. multiButton.SetFirstButton();
  122. multiButton.ButtonChangedEvent += ButtonChanged;
  123. Title = "Deliveries";
  124. if (firstLoad)
  125. {
  126. await Task.Run(() => { Thread.Sleep(1500); firstLoad = false; });
  127. }
  128. });
  129. });
  130. }
  131. protected override async void OnAppearing()
  132. {
  133. if (firstLoad)
  134. return;
  135. Title = "Refreshing";
  136. await Task.Run(() =>
  137. {
  138. LoadData();
  139. Device.BeginInvokeOnMainThread(() =>
  140. {
  141. ListSelectFromButton();
  142. Title = "Deliveries";
  143. });
  144. });
  145. base.OnAppearing();
  146. }
  147. private void LoadData()
  148. {
  149. deliveries.Clear();
  150. CoreTable table = new Client<Delivery>().Query(
  151. new Filter<Delivery>(x => x.Completed).IsEqualTo(DateTime.MinValue).Or(x => x.Completed).IsGreaterThanOrEqualTo(DateTime.Today.AddDays(-7)),
  152. new Columns<Delivery>(
  153. x => x.ID, //0
  154. x => x.Number, //1
  155. x => x.Job.Name, //2
  156. x => x.Assignment.Date, //3
  157. x => x.DeliveredBy.Name, //4
  158. x => x.Completed, //5
  159. x => x.Documents, //6
  160. x => x.Location.Latitude, //7
  161. x => x.Location.Longitude, //8
  162. x => x.Due, //9
  163. x => x.Delivered, //10
  164. x => x.Contact.Name, //11
  165. x => x.Location.Address //12
  166. ),
  167. new SortOrder<Delivery>(x => x.Completed, SortDirection.Descending)
  168. );
  169. string emptyString = "";
  170. foreach (var row in table.Rows)
  171. {
  172. List<object> list = row.Values;
  173. if (list[0] == null) { list[0] = Guid.Empty; }
  174. if (list[1] == null) { list[1] = 0; }
  175. if (list[2] == null) { list[2] = emptyString; }
  176. if (list[3] == null) { list[3] = DateTime.MinValue; }
  177. if (list[4] == null) { list[4] = emptyString; }
  178. if (list[5] == null) { list[5] = DateTime.MinValue; }
  179. if (list[6] == null) { list[6] = 0; }
  180. if (list[7] == null) { list[7] = 0; }
  181. if (list[8] == null) { list[8] = 0; }
  182. if (list[9] == null) { list[9] = DateTime.MinValue; }
  183. if (list[10] == null) { list[10] = DateTime.MinValue; }
  184. if (list[11] == null) { list[11] = emptyString; }
  185. if (list[12] == null) { list[12] = emptyString; }
  186. DeliveryShell deliveryShell = new DeliveryShell();
  187. deliveryShell.ID = Guid.Parse(list[0].ToString());
  188. deliveryShell.Number = int.Parse(list[1].ToString());
  189. deliveryShell.JobName = list[2].ToString();
  190. if (list[3].Equals(DateTime.MinValue))
  191. {
  192. deliveryShell.AssignmentDate = "";
  193. }
  194. else
  195. {
  196. deliveryShell.AssignmentDate = DateTime.Parse(list[3].ToString()).ToString("dd MMM yy");
  197. }
  198. deliveryShell.EmployeeName = list[4].ToString();
  199. deliveryShell.Completed = DateTime.Parse(list[5].ToString());
  200. deliveryShell.Documents = int.Parse(list[6].ToString());
  201. deliveryShell.Due = DateTime.Parse(list[9].ToString());
  202. deliveryShell.Delivered = DateTime.Parse(list[10].ToString());
  203. if (deliveryShell.Documents != 0)
  204. {
  205. if (Device.RuntimePlatform.Equals(Device.iOS))
  206. {
  207. deliveryShell.ClipImagePath = "attachments";
  208. }
  209. else deliveryShell.ClipImagePath = "paperclip.png";
  210. }
  211. if (double.Parse(list[7].ToString()) != 0 && double.Parse(list[8].ToString()) != 0)
  212. {
  213. if (Device.RuntimePlatform.Equals(Device.iOS))
  214. {
  215. deliveryShell.LocationImagePath = "locationmarker";
  216. }
  217. else deliveryShell.LocationImagePath = "locationpointer.png";
  218. }
  219. deliveryShell.Latitude = double.Parse(list[7].ToString());
  220. deliveryShell.Longitude = double.Parse(list[8].ToString());
  221. deliveryShell.Contact = list[11].ToString();
  222. if (deliveryShell.Delivered != DateTime.MinValue)
  223. deliveryShell.DisplayDelivered = deliveryShell.Delivered.ToString("dd MMM yy");
  224. deliveryShell.DeliveredAddress = list[12].ToString();
  225. deliveries.Add(deliveryShell);
  226. }
  227. }
  228. private async void Delivery_Clicked(object sender, EventArgs e)
  229. {
  230. var delivery = deliveriesListView.SelectedItem as DeliveryShell;
  231. string loadingMessage = "Loading Delivery " + delivery.Number;
  232. if (delivery.Documents != 0)
  233. {
  234. loadingMessage = loadingMessage + " with " + delivery.Documents + " attached document(s). Please wait for photos to appear.";
  235. }
  236. using (await MaterialDialog.Instance.LoadingDialogAsync(message: loadingMessage))
  237. {
  238. var details = new DeliveryDetails(delivery.ID);
  239. Navigation.PushAsync(details);
  240. }
  241. }
  242. private void AddDelivery_Clicked(object sender, EventArgs e)
  243. {
  244. Delivery delivery = new Delivery();
  245. var details = new DeliveryDetails(delivery.ID);
  246. Navigation.PushAsync(details);
  247. }
  248. private void ButtonChanged(object sender, EventArgs e)
  249. {
  250. ListSelectFromButton();
  251. }
  252. private void ListSelectFromButton()
  253. {
  254. if (multiButton.ButtonSelected != null)
  255. {
  256. if (multiButton.ButtonSelected.Equals(multiButton.Button1Text))
  257. {
  258. AdjustOpenList();
  259. includUnbookedBtn.IsEnabled = true;
  260. }
  261. if (multiButton.ButtonSelected.Equals(multiButton.Button2Text))
  262. {
  263. deliveriesListView.ItemsSource = deliveries.Where(x => x.Delivered.Date.Equals(Today));
  264. includUnbookedBtn.IsEnabled = false;
  265. }
  266. if (multiButton.ButtonSelected.Equals(multiButton.Button3Text))
  267. {
  268. deliveriesListView.ItemsSource = deliveries.Where(x => x.Delivered >= (DateTime.Today.AddDays(-7)) || x.Completed >= (DateTime.Today.AddDays(-7)));
  269. includUnbookedBtn.IsEnabled = false;
  270. }
  271. }
  272. }
  273. private void Image_Tapped(object sender, EventArgs e)
  274. {
  275. var shell = ((TappedEventArgs)e).Parameter as DeliveryShell;
  276. if (shell == null)
  277. return;
  278. if (!string.IsNullOrWhiteSpace(shell.DeliveredAddress))
  279. {
  280. popupLayout.PopupView.ShowHeader = false;
  281. popupLayout.PopupView.ShowFooter = false;
  282. popupLayout.PopupView.ContentTemplate = new DataTemplate(() =>
  283. {
  284. Label lbl = new Label();
  285. lbl.Margin = new Thickness(10);
  286. lbl.FontSize = Device.GetNamedSize(NamedSize.Medium, lbl);
  287. lbl.FontAttributes = FontAttributes.Bold;
  288. lbl.HorizontalOptions = LayoutOptions.Center;
  289. lbl.VerticalOptions = LayoutOptions.Center;
  290. lbl.HorizontalTextAlignment = TextAlignment.Center;
  291. lbl.LineBreakMode = LineBreakMode.WordWrap;
  292. lbl.Text = shell.DeliveredAddress + " at " + shell.Delivered.ToString("hh:mm:ss tt dd MMM yy") + System.Environment.NewLine
  293. + "by: " + shell.EmployeeName;
  294. Button btn = new Button
  295. {
  296. BackgroundColor = Color.FromHex("#15C7C1"),
  297. Text = "View in Maps",
  298. FontAttributes = FontAttributes.Bold,
  299. TextColor = Color.White,
  300. CornerRadius = 10,
  301. HorizontalOptions = LayoutOptions.Center,
  302. };
  303. btn.FontSize = Device.GetNamedSize(NamedSize.Medium, btn);
  304. btn.Clicked += async (object sender, EventArgs e) =>
  305. {
  306. var location = new Xamarin.Essentials.Location(shell.Latitude, shell.Longitude);
  307. var options = new MapLaunchOptions { };
  308. await Map.OpenAsync(location, options);
  309. };
  310. Image img = new Image
  311. {
  312. HorizontalOptions = LayoutOptions.Center,
  313. HeightRequest = 40,
  314. WidthRequest = 40
  315. };
  316. if (Device.RuntimePlatform.Equals(Device.iOS))
  317. {
  318. img.Source = "locationmarker.png";
  319. }
  320. else img.Source = "locationpointer.png";
  321. img.Margin = new Thickness(10, 30, 10, 10);
  322. StackLayout stack = new StackLayout();
  323. stack.Margin = new Thickness(20, 50, 20, 50);
  324. stack.Children.Add(img);
  325. stack.Children.Add(lbl);
  326. stack.Children.Add(btn);
  327. return stack;
  328. });
  329. popupLayout.Show();
  330. }
  331. }
  332. private void AdjustOpenList()
  333. {
  334. if (includeUnbooked)
  335. {
  336. deliveriesListView.ItemsSource = deliveries.Where(x => x.Delivered.Equals(DateTime.MinValue));
  337. }
  338. else if (!includeUnbooked)
  339. {
  340. var list = deliveries.Where(x => x.Delivered.Equals(DateTime.MinValue));
  341. List<DeliveryShell> excludeUnbooked = new List<DeliveryShell>();
  342. foreach (DeliveryShell shell in list)
  343. {
  344. if (!string.IsNullOrWhiteSpace(shell.AssignmentDate))
  345. {
  346. excludeUnbooked.Add(shell);
  347. }
  348. }
  349. deliveriesListView.ItemsSource = excludeUnbooked;
  350. }
  351. }
  352. private void IncludeUnbookedBtn_Clicked(object sender, EventArgs e)
  353. {
  354. if (includeUnbooked)
  355. {
  356. includeUnbooked = false;
  357. includUnbookedBtn.BackgroundColor = Color.FromHex("#15C7C1");
  358. includUnbookedBtn.Text = "Include Unbooked (Off)";
  359. }
  360. else if (!includeUnbooked)
  361. {
  362. includeUnbooked = true;
  363. includUnbookedBtn.BackgroundColor = Color.Gray;
  364. includUnbookedBtn.Text = "Include Unbooked (On)";
  365. }
  366. AdjustOpenList();
  367. }
  368. */
  369. }
  370. }