DigitalFormsPicker.xaml.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. using Comal.Classes;
  2. using comal.timesheets.QAForms;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8. using Comal.Classes;
  9. using InABox.Clients;
  10. using InABox.Configuration;
  11. using InABox.Core;
  12. using System.Linq;
  13. using System.Threading;
  14. using System.Threading.Tasks;
  15. using comal.timesheets.Data_Classes;
  16. using Xamarin.Forms;
  17. using Xamarin.Forms.Xaml;
  18. using XF.Material.Forms.UI.Dialogs;
  19. namespace comal.timesheets
  20. {
  21. [XamlCompilation(XamlCompilationOptions.Compile)]
  22. public partial class DigitalFormsPicker : ContentPage
  23. {
  24. #region Fields
  25. bool _searching = false;
  26. Kanban addToTaskKanban = new Kanban();
  27. List<DigitalFormLayoutShell> layouts = new List<DigitalFormLayoutShell>();
  28. List<String> types = new List<String>();
  29. private bool firstLoad = true;
  30. private bool incompleteVisible = true;
  31. private bool addingToTask = false;
  32. Guid JobID = Guid.Empty;
  33. List<ExistingFormShell> incompleteForms = new List<ExistingFormShell>();
  34. List<ExistingFormShell> completeForms = new List<ExistingFormShell>();
  35. #endregion
  36. public DigitalFormsPicker(string appliesTo = "Kanban", Guid _jobid = new Guid()) //normal Forms Library - default is kanban type
  37. {
  38. InitializeComponent();
  39. JobID = _jobid;
  40. NavigationPage.SetHasBackButton(this, false);
  41. LoadScreen(appliesTo);
  42. }
  43. public DigitalFormsPicker(Kanban _kanban) //used for adding forms to a task
  44. {
  45. InitializeComponent();
  46. addingToTask = true;
  47. addToTaskKanban = _kanban;
  48. NavigationPage.SetHasBackButton(this, false);
  49. LoadScreen("Kanban");
  50. }
  51. private void ExitBtn_Clicked(object sender, EventArgs e)
  52. {
  53. Navigation.PopAsync();
  54. }
  55. #region OnAppearing and Loading Screen
  56. protected override void OnAppearing()
  57. {
  58. try
  59. {
  60. _searching = false;
  61. if (RetainedResults.IsFormRetained)
  62. {
  63. DigitalFormHost host = new DigitalFormHost(LoadModel(RetainedResults.LastDigitalFormLayout, CheckType()), JobID);
  64. Navigation.PushAsync(host);
  65. }
  66. LoadExistingForms();
  67. }
  68. catch { }
  69. base.OnAppearing();
  70. }
  71. private void LoadScreen(string appliesTo)
  72. {
  73. try
  74. {
  75. Task.Run(()=>
  76. {
  77. types.Add("All");
  78. CoreTable table = LoadEmployeeRoleForms(appliesTo);
  79. foreach (CoreRow row in table.Rows)
  80. CreateAndAddShell(row);
  81. GetAverages();
  82. Device.BeginInvokeOnMainThread(() =>
  83. {
  84. layoutsList.ItemsSource = layouts;
  85. filterOptionsControl.Options = types;
  86. filterOptionsControl.CreateRadioButtonsAndSetDefault(types.First());
  87. });
  88. filterOptionsControl.OnFilterOptionChanged += FilterOptionsControl_OnFilterOptionChanged;
  89. firstLoad = false;
  90. });
  91. }
  92. catch (Exception e)
  93. {
  94. DisplayAlert("Error", e.Message, "OK");
  95. }
  96. }
  97. private void CreateAndAddShell(CoreRow row)
  98. {
  99. DigitalFormLayoutShell layout = new DigitalFormLayoutShell();
  100. layout.ID = row.Get<DigitalFormLayout, Guid>(x => x.ID);
  101. layout.Description = row.Get<DigitalFormLayout, string>(x => x.Description);
  102. layout.Code = row.Get<DigitalFormLayout, string>(x => x.Code);
  103. layout.AppliesTo = row.Get<DigitalFormLayout, string>(x => x.Form.AppliesTo);
  104. layout.FormID = row.Get<DigitalFormLayout, Guid>(x => x.Form.ID);
  105. layout.Layout = row.Get<DigitalFormLayout, string>(x => x.Layout);
  106. layout.FormGroupDescription = row.Get<DigitalFormLayout, string>(x => x.Form.Group.Description);
  107. if (string.IsNullOrWhiteSpace(layout.FormGroupDescription))
  108. layout.FormGroupDescription = "All";
  109. layouts.Add(layout);
  110. if (!types.Contains(layout.FormGroupDescription) && !string.IsNullOrWhiteSpace(layout.FormGroupDescription))
  111. {
  112. types.Add(layout.FormGroupDescription);
  113. }
  114. }
  115. private CoreTable LoadEmployeeRoleForms(string appliesTo)
  116. {
  117. CoreTable table = new Client<EmployeeRole>().Query(
  118. new Filter<EmployeeRole>(x => x.EmployeeLink.ID).IsEqualTo(GlobalVariables.EmpID)
  119. , new Columns<EmployeeRole>(x => x.RoleLink.ID));
  120. if (!table.Rows.Any())
  121. {
  122. DisplayAlert("Alert", "No Roles found for your employee profile. Please check with your administrator.", "OK");
  123. return table;
  124. }
  125. CoreTable roleForms = QueryRoleForms(table);
  126. if (!roleForms.Rows.Any())
  127. {
  128. DisplayAlert("Alert", "No Forms found for your employee role. Please check with your administrator.", "OK");
  129. return table;
  130. }
  131. return QueryFormLayouts(roleForms, appliesTo);
  132. }
  133. private CoreTable QueryRoleForms(CoreTable table)
  134. {
  135. List<Guid> roleIDS = new List<Guid>();
  136. foreach (CoreRow row in table.Rows)
  137. {
  138. roleIDS.Add(row.Get<EmployeeRole, Guid>(x => x.RoleLink.ID));
  139. }
  140. return new Client<RoleForm>().Query(
  141. new Filter<RoleForm>(x => x.Role.ID).InList(roleIDS.ToArray()),
  142. new Columns<RoleForm>(x => x.Form.ID));
  143. }
  144. private CoreTable QueryFormLayouts(CoreTable roleForms, string appliesTo)
  145. {
  146. List<Guid> formIDs = new List<Guid>();
  147. foreach (CoreRow row in roleForms.Rows)
  148. {
  149. formIDs.Add(row.Get<RoleForm, Guid>(x => x.Form.ID));
  150. }
  151. return new Client<DigitalFormLayout>().Query
  152. (
  153. new Filter<DigitalFormLayout>(x => x.Form.ID).InList(formIDs.ToArray())
  154. .And(x => x.Type).IsEqualTo(DFLayoutType.Mobile)
  155. .And(x => x.Active).IsEqualTo(true)
  156. .And(x => x.Form.Secure).IsEqualTo(false)
  157. .And(x => x.Form.Active).IsEqualTo(true)
  158. .And(x => x.Form.AppliesTo).IsEqualTo(appliesTo),
  159. new Columns<DigitalFormLayout>(
  160. x => x.Description,
  161. x => x.ID,
  162. x => x.Code,
  163. x => x.Form.AppliesTo,
  164. x => x.Form.ID,
  165. x => x.Layout,
  166. x => x.Form.Group.Description),
  167. new SortOrder<DigitalFormLayout>(x => x.Description)
  168. );
  169. }
  170. private void GetAverages()
  171. {
  172. try
  173. {
  174. Task.Run(() =>
  175. {
  176. foreach (var layout in layouts)
  177. {
  178. TimeSpan span = new TimeSpan();
  179. CoreTable table = new Client<KanbanForm>().Query
  180. (
  181. new Filter<KanbanForm>(x => x.Form.ID).IsEqualTo(layout.FormID).And(x => x.FormOpen).IsNotEqualTo(null),
  182. new Columns<KanbanForm>(x => x.FormOpen)
  183. );
  184. if (table.Rows.Any())
  185. {
  186. foreach (CoreRow row in table.Rows)
  187. {
  188. List<object> list = row.Values;
  189. TimeSpan timespan = TimeSpan.Parse(list[0].ToString());
  190. span = span + timespan;
  191. }
  192. TimeSpan average = span / table.Rows.Count();
  193. layout.AverageTime = "Average time to complete: " + average.Minutes.ToString() + "m " + average.Seconds.ToString() + "s";
  194. layout.AverageTimeRow = 30;
  195. layout.ImageRowSpan = 2;
  196. }
  197. }
  198. Device.BeginInvokeOnMainThread(() =>
  199. {
  200. layoutsList.ItemsSource = null;
  201. if (filterOptionsControl.CurrentOption == "All")
  202. {
  203. layoutsList.ItemsSource = layouts;
  204. }
  205. else
  206. {
  207. layoutsList.ItemsSource = layouts.Where(x => x.FormGroupDescription.Equals(filterOptionsControl.CurrentOption));
  208. }
  209. });
  210. });
  211. }
  212. catch { }
  213. }
  214. private void LoadExistingForms()
  215. {
  216. //Task.Run(() =>
  217. //{
  218. try
  219. {
  220. List<IFormPickerQueryLoader> loaderList = new List<IFormPickerQueryLoader>()
  221. {
  222. new FormPickerQueryLoader<Kanban, KanbanLink, KanbanForm>(),
  223. new FormPickerQueryLoader<Job, JobLink, JobForm>()
  224. };
  225. incompleteForms.Clear();
  226. completeForms.Clear();
  227. foreach (var loader in loaderList)
  228. {
  229. List<ExistingFormShell> incomplete = loader.QueryIncomplete();
  230. foreach (var v in incomplete)
  231. {
  232. incompleteForms.Add(v);
  233. }
  234. List<ExistingFormShell> complete = loader.QueryComplete();
  235. foreach (var v in complete)
  236. {
  237. completeForms.Add(v);
  238. }
  239. }
  240. Device.BeginInvokeOnMainThread(() =>
  241. {
  242. ShowOrHideIncompleteFormsNotifications();
  243. RefreshMyForms();
  244. });
  245. }
  246. catch { }
  247. //});
  248. }
  249. private void ShowOrHideIncompleteFormsNotifications()
  250. {
  251. if (incompleteForms.Count > 0)
  252. {
  253. notificationFrame.IsVisible = true;
  254. notificationColumn.Width = 40;
  255. numberOfIncompleteFormsLbl.Text = incompleteForms.Count.ToString();
  256. }
  257. else
  258. {
  259. notificationFrame.IsVisible = false;
  260. notificationColumn.Width = 0;
  261. }
  262. }
  263. private void RefreshMyForms()
  264. {
  265. incompleteFormsList.ItemsSource = null;
  266. completeFormsList.ItemsSource = null;
  267. incompleteFormsList.ItemsSource = incompleteForms;
  268. completeFormsList.ItemsSource = completeForms;
  269. incompleteBtn.Text = "Incomplete (" + incompleteForms.Count + ")";
  270. completeBtn.Text = "Complete (" + completeForms.Count + ")";
  271. }
  272. #endregion
  273. #region User Interaction
  274. #region New Forms Section
  275. private void NewButton_Clicked(object sender, EventArgs e)
  276. {
  277. templatesColumn.Width = GridLength.Star;
  278. formsColumn.Width = 0;
  279. existingFormsGrid.IsVisible = false;
  280. templatesGrid.IsVisible = true;
  281. newButton.BackgroundColor = Color.FromHex("#15C7C1");
  282. myFormsButton.BackgroundColor = Color.Default;
  283. }
  284. private void MyFormsButton_Clicked(object sender, EventArgs e)
  285. {
  286. templatesColumn.Width = 0;
  287. formsColumn.Width = GridLength.Star;
  288. existingFormsGrid.IsVisible = true;
  289. templatesGrid.IsVisible = false;
  290. newButton.BackgroundColor = Color.Default;
  291. myFormsButton.BackgroundColor = Color.FromHex("#15C7C1");
  292. }
  293. private void FilterOptionsControl_OnFilterOptionChanged(string filterOption)
  294. {
  295. try
  296. {
  297. if (filterOption == filterOptionsControl.CurrentOption)
  298. return;
  299. filterOptionsControl.CurrentOption = filterOption;
  300. if (filterOption == "All")
  301. {
  302. layoutsList.ItemsSource = layouts;
  303. }
  304. else
  305. {
  306. layoutsList.ItemsSource = layouts.Where(x => x.FormGroupDescription.Equals(filterOption));
  307. }
  308. }
  309. catch { }
  310. }
  311. #endregion
  312. #region My Forms Section
  313. private async void IncompleteFormsList_Tapped(object sender, EventArgs e)
  314. {
  315. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading"))
  316. {
  317. var form = incompleteFormsList.SelectedItem as ExistingFormShell;
  318. DigitalFormLayout layout = new Client<DigitalFormLayout>().Query(
  319. new Filter<DigitalFormLayout>(x => x.Form.ID).IsEqualTo(form.FormID)
  320. ).Rows.FirstOrDefault().ToObject<DigitalFormLayout>();
  321. if (form.Type == typeof(JobForm))
  322. JobID = form.ParentID;
  323. else
  324. JobID = Guid.Empty;
  325. DigitalFormHost host = new DigitalFormHost(LoadModel(layout, form.Type, form), JobID);
  326. Navigation.PushAsync(host);
  327. }
  328. }
  329. private async void CompleteFormsList_Tapped(object sender, EventArgs e)
  330. {
  331. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading"))
  332. {
  333. var form = completeFormsList.SelectedItem as ExistingFormShell;
  334. DigitalFormLayout layout = new Client<DigitalFormLayout>().Query(
  335. new Filter<DigitalFormLayout>(x => x.Form.ID).IsEqualTo(form.FormID)
  336. ).Rows.FirstOrDefault().ToObject<DigitalFormLayout>();
  337. if (form.Type == typeof(JobForm))
  338. JobID = form.ParentID;
  339. else
  340. JobID = Guid.Empty;
  341. DigitalFormHost host = new DigitalFormHost(LoadModel(layout, form.Type, form), JobID);
  342. Navigation.PushAsync(host);
  343. }
  344. }
  345. private void Incomplete_Tapped(object sender, EventArgs e)
  346. {
  347. incompleteFormsColumn.Width = GridLength.Star;
  348. completeFormsColumn.Width = 0;
  349. incompleteFormsList.IsVisible = true;
  350. completeFormsList.IsVisible = false;
  351. incompleteBtn.BackgroundColor = Color.FromHex("#15C7C1");
  352. completeBtn.BackgroundColor = Color.Default;
  353. incompleteVisible = true;
  354. searchEnt.Text = "";
  355. }
  356. private void Complete_Tapped(object sender, EventArgs e)
  357. {
  358. completeFormsColumn.Width = GridLength.Star;
  359. incompleteFormsColumn.Width = 0;
  360. completeFormsList.IsVisible = true;
  361. incompleteFormsList.IsVisible = false;
  362. incompleteBtn.BackgroundColor = Color.Default;
  363. completeBtn.BackgroundColor = Color.FromHex("#15C7C1");
  364. incompleteVisible = false;
  365. searchEnt.Text = "";
  366. }
  367. #region Loading From History Section
  368. private void LayoutsList_Tapped(object sender, EventArgs e)
  369. {
  370. if (_searching)
  371. return;
  372. else
  373. LoadHost();
  374. }
  375. private async void LoadHost()
  376. {
  377. try
  378. {
  379. var digitalFormLayoutShell = layoutsList.SelectedItem as DigitalFormLayoutShell;
  380. DigitalFormLayout digitalFormLayout = new DigitalFormLayout();
  381. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading"))
  382. {
  383. _searching = true;
  384. digitalFormLayout.ID = digitalFormLayoutShell.ID;
  385. digitalFormLayout.Description = digitalFormLayoutShell.Description;
  386. digitalFormLayout.Code = digitalFormLayoutShell.Code;
  387. digitalFormLayout.Form.AppliesTo = digitalFormLayoutShell.AppliesTo;
  388. digitalFormLayout.Form.ID = digitalFormLayoutShell.FormID;
  389. digitalFormLayout.Layout = digitalFormLayoutShell.Layout;
  390. digitalFormLayout.Form.Group.Description = digitalFormLayoutShell.FormGroupDescription;
  391. RetainedResults.LastDigitalFormLayout = digitalFormLayout;
  392. }
  393. DigitalFormHost host = new DigitalFormHost(LoadModel(digitalFormLayout, CheckType()), JobID);
  394. Navigation.PushAsync(host);
  395. }
  396. catch { }
  397. }
  398. private Type CheckType()
  399. {
  400. if (JobID != Guid.Empty)
  401. return typeof(JobForm);
  402. else
  403. return typeof(KanbanForm);
  404. }
  405. private IDigitalFormHostModel LoadModel(DigitalFormLayout layout, Type type, ExistingFormShell form = null)
  406. {
  407. if (type == typeof(JobForm))
  408. {
  409. var model = new DigitalFormHostModel<Job, JobLink, JobForm>();
  410. var job = new Job();
  411. var jobForm = new JobForm();
  412. jobForm.Form.ID = layout.Form.ID;
  413. if (form == null)
  414. {
  415. job.ID = JobID;
  416. }
  417. else
  418. {
  419. jobForm.ID = form.ID;
  420. job.ID = form.ParentID;
  421. }
  422. model.LoadItems(job, jobForm, layout);
  423. return model;
  424. }
  425. else
  426. {
  427. var model = new DigitalFormHostModel<Kanban, KanbanLink, KanbanForm>();
  428. var kanban = new Kanban();
  429. var kanbanForm = new KanbanForm();
  430. kanbanForm.Form.ID = layout.Form.ID;
  431. if (form != null)
  432. {
  433. kanbanForm.ID = form.ID;
  434. kanban.ID = form.ParentID;
  435. }
  436. if (addingToTask)
  437. {
  438. kanbanForm.Parent.ID = addToTaskKanban.ID;
  439. kanban.ID = addToTaskKanban.ID;
  440. }
  441. model.LoadItems(kanban, kanbanForm, layout);
  442. return model;
  443. }
  444. }
  445. #endregion
  446. #region Searching
  447. private void SearchEnt_Changed(object sender, EventArgs e)
  448. {
  449. if (CheckEmptySearch())
  450. return;
  451. else
  452. {
  453. RunSearch();
  454. }
  455. }
  456. private bool CheckEmptySearch()
  457. {
  458. if (string.IsNullOrWhiteSpace(searchEnt.Text))
  459. {
  460. incompleteFormsList.ItemsSource = incompleteForms;
  461. completeFormsList.ItemsSource = completeForms;
  462. return true;
  463. }
  464. else
  465. return false;
  466. }
  467. private void RunSearch()
  468. {
  469. try
  470. {
  471. if (incompleteVisible)
  472. RunSearchOnIncomplete();
  473. else
  474. RunSearchOnHistory();
  475. }
  476. catch (Exception ex)
  477. {
  478. string message = ex.Message;
  479. }
  480. }
  481. private void RunSearchOnIncomplete()
  482. {
  483. incompleteFormsList.ItemsSource = incompleteForms.Where(x =>
  484. x.Description.Contains(searchEnt.Text) || x.Description.Contains(searchEnt.Text.ToUpper())
  485. || x.Description.Contains(searchEnt.Text.ToLower()) || x.Description.Contains(SearchUtils.UpperCaseFirst(searchEnt.Text))
  486. );
  487. }
  488. private void RunSearchOnHistory()
  489. {
  490. completeFormsList.ItemsSource = completeForms.Where(x =>
  491. x.Description.Contains(searchEnt.Text) || x.Description.Contains(searchEnt.Text.ToUpper())
  492. || x.Description.Contains(searchEnt.Text.ToLower()) || x.Description.Contains(SearchUtils.UpperCaseFirst(searchEnt.Text))
  493. );
  494. }
  495. #endregion
  496. #endregion
  497. #endregion
  498. }
  499. }