QAFormPicker.xaml.cs 20 KB

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