AddEditQualification.xaml.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. 
  2. using Comal.Classes;
  3. using InABox.Clients;
  4. using InABox.Core;
  5. using Plugin.Media;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading;
  12. using System.Threading.Tasks;
  13. using Xamarin.Forms;
  14. using Xamarin.Forms.Xaml;
  15. using XF.Material.Forms.UI.Dialogs;
  16. namespace comal.timesheets
  17. {
  18. [XamlCompilation(XamlCompilationOptions.Compile)]
  19. public partial class AddEditQualification
  20. {
  21. #region Fields, constructor + navigation
  22. EmployeeQualification EmpQualification = new EmployeeQualification();
  23. Dictionary<string, Qualification> descriptionQualifications = new Dictionary<string, Qualification>();
  24. PhotoType photoType = new PhotoType();
  25. Document frontPhotoDoc = new Document();
  26. Document backPhotoDoc = new Document();
  27. bool bFirstLoad = true;
  28. bool newEmpQualificationSaved = false;
  29. List<Qualification> qualifications = new List<Qualification>();
  30. Dictionary<string, Guid> fileNameIDs = new Dictionary<string, Guid>();
  31. public AddEditQualification(Guid empqualificationID)
  32. {
  33. InitializeComponent();
  34. photoType = PhotoType.Default;
  35. NavigationPage.SetHasBackButton(this, false);
  36. LoadScreen(empqualificationID);
  37. }
  38. protected override void OnAppearing()
  39. {
  40. addViewDocsBtn.IsEnabled = false;
  41. Task.Run(() =>
  42. {
  43. Thread.Sleep(1000);
  44. if (EmpQualification.ID != Guid.Empty)
  45. {
  46. CoreTable table = new Client<EmployeeQualificationDocument>().Query(new Filter<EmployeeQualificationDocument>(x => x.EntityLink.ID).IsEqualTo(EmpQualification.ID),
  47. new Columns<EmployeeQualificationDocument>(x => x.DocumentLink.ID));
  48. if (table.Rows.Any())
  49. {
  50. fileNameIDs.Clear();
  51. foreach (CoreRow row in table.Rows)
  52. {
  53. CoreTable docsTable = new Client<Document>().Query(new Filter<Document>(x => x.ID).IsEqualTo(Guid.Parse(row.Values[0].ToString())),
  54. new Columns<Document>(x => x.ID, x => x.FileName));
  55. Guid id = Guid.Parse(docsTable.Rows.First().Values[0].ToString());
  56. string str = docsTable.Rows.First().Values[1].ToString();
  57. if (!fileNameIDs.ContainsKey(str))
  58. fileNameIDs.Add(str, id);
  59. }
  60. }
  61. }
  62. Device.BeginInvokeOnMainThread(() =>
  63. {
  64. addViewDocsBtn.IsEnabled = true;
  65. documentsLbl.Text = "Documents (" + fileNameIDs.Count + ")";
  66. });
  67. });
  68. base.OnAppearing();
  69. }
  70. async void ExitBtn_Clicked(object sender, EventArgs e)
  71. {
  72. if (newEmpQualificationSaved)
  73. {
  74. CoreTable table = new Client<EmployeeQualificationDocument>().Query
  75. (
  76. new Filter<EmployeeQualificationDocument>(x => x.EntityLink.ID).IsEqualTo(EmpQualification.ID),
  77. new Columns<EmployeeQualificationDocument>(x => x.ID, x => x.DocumentLink.ID)
  78. );
  79. if (table.Rows.Any())
  80. {
  81. string chosenOption = await DisplayActionSheet("Alert", "You are exiting without saving. Continue?", null, "Yes", "No");
  82. switch (chosenOption)
  83. {
  84. case "Cancel":
  85. return;
  86. default:
  87. return;
  88. case "Yes":
  89. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Working"))
  90. {
  91. List<EmployeeQualificationDocument> empdocs = new List<EmployeeQualificationDocument>();
  92. List<Document> docs = new List<Document>();
  93. foreach (CoreRow row in table.Rows)
  94. {
  95. EmployeeQualificationDocument empdoc = new EmployeeQualificationDocument();
  96. empdoc.ID = Guid.Parse(row.Values[0].ToString());
  97. empdocs.Add(empdoc);
  98. Document doc = new Document();
  99. doc.ID = Guid.Parse(row.Values[1].ToString());
  100. docs.Add(doc);
  101. }
  102. new Client<EmployeeQualificationDocument>().Delete(empdocs, "Deleted from mobile device");
  103. new Client<Document>().Delete(docs, "Deleted from mobile device");
  104. }
  105. break;
  106. case "No":
  107. return;
  108. }
  109. }
  110. new Client<EmployeeQualification>().Delete(EmpQualification, "Deleted from mobile device");
  111. }
  112. Navigation.PopAsync();
  113. }
  114. async void Save_Clicked(object sender, EventArgs e)
  115. {
  116. if (qualificationPicker.SelectedIndex == -1)
  117. {
  118. DisplayAlert("Alert", "Choose a qualification first", "OK");
  119. return;
  120. }
  121. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving"))
  122. {
  123. EmpQualification.Employee.ID = App.Data.Me.ID;
  124. if (!string.IsNullOrWhiteSpace(frontPhotoDoc.FileName))
  125. {
  126. new Client<Document>().Save(frontPhotoDoc, "Saved from mobile device");
  127. EmpQualification.FrontPhoto.ID = frontPhotoDoc.ID;
  128. EmpQualification.Verified = DateTime.MinValue;
  129. }
  130. if (!string.IsNullOrWhiteSpace(backPhotoDoc.FileName))
  131. {
  132. new Client<Document>().Save(backPhotoDoc, "Saved from mobile device");
  133. EmpQualification.BackPhoto.ID = backPhotoDoc.ID;
  134. EmpQualification.Verified = DateTime.MinValue;
  135. }
  136. if (EmpQualification.Qualified == DateTime.MinValue)
  137. EmpQualification.Qualified = qualifiedDatePicker.Date;
  138. if (EmpQualification.Expiry == DateTime.MinValue)
  139. EmpQualification.Expiry = expiryDatePicker.Date;
  140. new Client<EmployeeQualification>().Save(EmpQualification, "Saved from mobile device");
  141. }
  142. await DisplayAlert("Succes", "Qualification saved for " + EmpQualification.Qualification.Description
  143. + ". This qualification is now awaiting verification.", "OK");
  144. Navigation.PopAsync();
  145. }
  146. #endregion
  147. #region Loading
  148. async void LoadScreen(Guid id)
  149. {
  150. try
  151. {
  152. if (id == Guid.Empty)
  153. {
  154. qualificationPicker.IsEnabled = true;
  155. }
  156. else
  157. {
  158. qualificationPicker.IsEnabled = false;
  159. descriptionFrame.BorderColor = Color.Gray;
  160. CoreTable table = new Client<EmployeeQualification>().Query(new Filter<EmployeeQualification>(x => x.ID).IsEqualTo(id),
  161. new Columns<EmployeeQualification>(x => x.ID, x => x.Qualification.ID, x => x.Qualification.Description, x => x.Expiry,
  162. x => x.Qualified, x => x.Verified, x => x.FrontPhoto.ID, x => x.BackPhoto.ID, x => x.Employee.ID, x => x.Qualification.Renewal,
  163. x => x.Qualification.Period));
  164. if (table.Rows.Any())
  165. {
  166. EmpQualification = table.Rows.FirstOrDefault().ToObject<EmployeeQualification>();
  167. }
  168. else
  169. {
  170. Device.BeginInvokeOnMainThread(() => { DisplayAlert("Error loading qualification", "", "OK"); });
  171. return;
  172. }
  173. if (EmpQualification.Qualified != DateTime.MinValue)
  174. {
  175. Device.BeginInvokeOnMainThread(() => { qualifiedDatePicker.Date = EmpQualification.Qualified; });
  176. }
  177. if (EmpQualification.Expiry != DateTime.MinValue)
  178. {
  179. Device.BeginInvokeOnMainThread(() => { expiryDatePicker.Date = EmpQualification.Expiry; });
  180. }
  181. }
  182. RefreshPhotoButtons();
  183. LoadQualifications();
  184. Task.Run(() =>
  185. {
  186. Thread.Sleep(1000);
  187. bFirstLoad = false;
  188. });
  189. }
  190. catch { }
  191. }
  192. void LoadQualifications()
  193. {
  194. try
  195. {
  196. Task.Run(() =>
  197. {
  198. CoreTable table = new Client<Qualification>().Query(null,
  199. new Columns<Qualification>(x => x.ID, x => x.Description, x => x.Renewal, x => x.Period)
  200. );
  201. foreach (CoreRow row in table.Rows)
  202. {
  203. Qualification qualification = row.ToObject<Qualification>();
  204. if (!descriptionQualifications.ContainsKey(qualification.Description))
  205. {
  206. descriptionQualifications.Add(qualification.Description, qualification);
  207. }
  208. }
  209. Device.BeginInvokeOnMainThread(() =>
  210. {
  211. qualificationPicker.ItemsSource = descriptionQualifications.Keys.ToList();
  212. if (EmpQualification.Qualification.ID != Guid.Empty)
  213. {
  214. qualificationPicker.SelectedIndex = descriptionQualifications.Keys.ToList().FindIndex(x => x.Equals(EmpQualification.Qualification.Description));
  215. ShowRenewal();
  216. }
  217. });
  218. });
  219. }
  220. catch { }
  221. }
  222. void ShowRenewal()
  223. {
  224. if (EmpQualification.Qualification.Renewal.Equals(QualificationRenewal.Permanent) ||
  225. EmpQualification.Qualification.Renewal.Equals(QualificationRenewal.Manual))
  226. {
  227. renewalLbl.Text = EmpQualification.Qualification.Renewal.ToString();
  228. }
  229. else
  230. {
  231. renewalLbl.Text = EmpQualification.Qualification.Period.ToString() + " " + EmpQualification.Qualification.Renewal;
  232. }
  233. if (EmpQualification.Qualification.Renewal.Equals(QualificationRenewal.Permanent))
  234. {
  235. EmpQualification.Expiry = DateTime.MaxValue;
  236. expiryDatePicker.Date = DateTime.MaxValue;
  237. expiryDatePicker.IsEnabled = false;
  238. Task.Run(() =>
  239. {
  240. Device.BeginInvokeOnMainThread(() =>
  241. {
  242. expiryDatePicker.BackgroundColor = Color.LightGreen;
  243. expiryDatePicker.Date = EmpQualification.Expiry;
  244. });
  245. Thread.Sleep(1200);
  246. Device.BeginInvokeOnMainThread(() => { expiryDatePicker.BackgroundColor = Color.Default; });
  247. });
  248. }
  249. else
  250. {
  251. expiryDatePicker.IsEnabled = true;
  252. if (EmpQualification.Expiry != DateTime.MinValue)
  253. {
  254. expiryDatePicker.Date = EmpQualification.Expiry;
  255. }
  256. else
  257. {
  258. EmpQualification.Expiry = DateTime.Today;
  259. }
  260. }
  261. }
  262. #endregion
  263. #region Response to fields changing / Taps
  264. async void AddViewDocsBtn_Clicked(object sender, EventArgs e)
  265. {
  266. if (qualificationPicker.SelectedIndex == -1)
  267. {
  268. DisplayAlert("Error", "Select a qualification first", "OK");
  269. return;
  270. }
  271. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading"))
  272. {
  273. if (EmpQualification.ID == Guid.Empty)
  274. {
  275. new Client<EmployeeQualification>().Save(EmpQualification, "Saved from mobile device");
  276. newEmpQualificationSaved = true;
  277. }
  278. PDFList pdfList = new PDFList(); //fileNameIDs, EmpQualification, true, true, true, false);
  279. Navigation.PushAsync(pdfList);
  280. }
  281. }
  282. void QualificationPicker_IndexChanged(object sender, EventArgs e)
  283. {
  284. if (!bFirstLoad)
  285. {
  286. EmpQualification.Qualification.ID = descriptionQualifications[qualificationPicker.SelectedItem.ToString()].ID;
  287. EmpQualification.Qualification.Description = qualificationPicker.SelectedItem.ToString();
  288. EmpQualification.Qualification.Renewal = descriptionQualifications[qualificationPicker.SelectedItem.ToString()].Renewal;
  289. EmpQualification.Qualification.Period = descriptionQualifications[qualificationPicker.SelectedItem.ToString()].Period;
  290. ShowRenewal();
  291. }
  292. }
  293. void QualifiedDatePicker_Selected(object sender, DateChangedEventArgs e)
  294. {
  295. if (!bFirstLoad)
  296. {
  297. EmpQualification.Qualified = qualifiedDatePicker.Date;
  298. EmpQualification.Verified = DateTime.MinValue;
  299. Task.Run(() =>
  300. {
  301. Thread.Sleep(300);
  302. Device.BeginInvokeOnMainThread(() =>
  303. {
  304. expiryDatePicker.BackgroundColor = Color.LightGreen;
  305. expiryDatePicker.Date = EmpQualification.Expiry;
  306. });
  307. Thread.Sleep(1200);
  308. Device.BeginInvokeOnMainThread(() => { expiryDatePicker.BackgroundColor = Color.Default; });
  309. });
  310. }
  311. }
  312. void ExpiryDatePicker_Selected(object sender, DateChangedEventArgs e)
  313. {
  314. if (!bFirstLoad)
  315. {
  316. EmpQualification.Expiry = expiryDatePicker.Date;
  317. EmpQualification.Verified = DateTime.MinValue;
  318. }
  319. }
  320. #endregion
  321. #region Photos
  322. void TakeFrontPhoto_Clicked(object sender, EventArgs e)
  323. {
  324. photoType = PhotoType.FrontPhoto;
  325. OpenCamera();
  326. }
  327. void TakeBackPhoto_Clicked(object sender, EventArgs e)
  328. {
  329. photoType = PhotoType.BackPhoto;
  330. OpenCamera();
  331. }
  332. private async void OpenCamera()
  333. {
  334. try
  335. {
  336. await CrossMedia.Current.Initialize();
  337. if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
  338. {
  339. return;
  340. }
  341. String filename = String.Format("{0:yyyy-MM-dd HH:mm:ss.fff}.png", DateTime.Now);
  342. var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
  343. {
  344. Name = filename,
  345. CompressionQuality = 40,
  346. PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full,
  347. SaveMetaData = false
  348. });
  349. if (file == null)
  350. return;
  351. AddPhoto(file);
  352. }
  353. catch
  354. { }
  355. }
  356. private async void AddPhoto(Plugin.Media.Abstractions.MediaFile file)
  357. {
  358. try
  359. {
  360. using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo"))
  361. {
  362. var memoryStream = new MemoryStream();
  363. file.GetStream().CopyTo(memoryStream);
  364. var data = memoryStream.ToArray();
  365. Document doc = new Document()
  366. {
  367. FileName = Path.GetFileName(file.Path),
  368. Data = data,
  369. CRC = CoreUtils.CalculateCRC(data),
  370. TimeStamp = DateTime.Now
  371. };
  372. if (photoType.Equals(PhotoType.FrontPhoto))
  373. frontPhotoDoc = doc;
  374. else if (photoType.Equals(PhotoType.BackPhoto))
  375. backPhotoDoc = doc;
  376. RefreshPhotoButtons();
  377. DisplayAlert("Success", "Photo added. Save to complete the process. This photo is not saved to or available on your device", "OK");
  378. }
  379. }
  380. catch
  381. { }
  382. }
  383. void RefreshPhotoButtons()
  384. {
  385. Device.BeginInvokeOnMainThread(() =>
  386. {
  387. if (EmpQualification.FrontPhoto.ID != Guid.Empty || !string.IsNullOrWhiteSpace(frontPhotoDoc.FileName))
  388. {
  389. TakeFrontPhotoBtn.Text = "Photo added";
  390. TakeFrontPhotoBtn.BackgroundColor = Color.FromHex("#15C7C1");
  391. }
  392. else
  393. {
  394. TakeFrontPhotoBtn.Text = "No photo added";
  395. TakeFrontPhotoBtn.BackgroundColor = Color.Orange;
  396. }
  397. if (EmpQualification.BackPhoto.ID != Guid.Empty || !string.IsNullOrWhiteSpace(backPhotoDoc.FileName))
  398. {
  399. TakeBackPhotoBtn.Text = "Photo added";
  400. TakeBackPhotoBtn.BackgroundColor = Color.FromHex("#15C7C1");
  401. }
  402. else
  403. {
  404. TakeBackPhotoBtn.Text = "No photo added";
  405. TakeBackPhotoBtn.BackgroundColor = Color.Orange;
  406. }
  407. });
  408. }
  409. #endregion
  410. #region Utils
  411. private void OnTap(object sender, EventArgs e)
  412. {
  413. ImageViewer viewer = new ImageViewer((sender as Image).Source);
  414. Navigation.PushAsync(viewer);
  415. }
  416. enum PhotoType
  417. {
  418. FrontPhoto,
  419. BackPhoto,
  420. Default
  421. }
  422. #endregion
  423. }
  424. }