using Comal.Classes; using InABox.Clients; using InABox.Core; using Plugin.Media; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using Xamarin.Forms; using Xamarin.Forms.Xaml; using XF.Material.Forms.UI.Dialogs; namespace comal.timesheets { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class AddEditQualification { #region Fields, constructor + navigation EmployeeQualification EmpQualification = new EmployeeQualification(); Dictionary descriptionQualifications = new Dictionary(); PhotoType photoType = new PhotoType(); Document frontPhotoDoc = new Document(); Document backPhotoDoc = new Document(); bool bFirstLoad = true; bool newEmpQualificationSaved = false; List qualifications = new List(); Dictionary fileNameIDs = new Dictionary(); public AddEditQualification(Guid empqualificationID) { InitializeComponent(); photoType = PhotoType.Default; NavigationPage.SetHasBackButton(this, false); LoadScreen(empqualificationID); } protected override void OnAppearing() { addViewDocsBtn.IsEnabled = false; Task.Run(() => { Thread.Sleep(1000); if (EmpQualification.ID != Guid.Empty) { CoreTable table = new Client().Query(new Filter(x => x.EntityLink.ID).IsEqualTo(EmpQualification.ID), new Columns(x => x.DocumentLink.ID)); if (table.Rows.Any()) { fileNameIDs.Clear(); foreach (CoreRow row in table.Rows) { CoreTable docsTable = new Client().Query(new Filter(x => x.ID).IsEqualTo(Guid.Parse(row.Values[0].ToString())), new Columns(x => x.ID, x => x.FileName)); Guid id = Guid.Parse(docsTable.Rows.First().Values[0].ToString()); string str = docsTable.Rows.First().Values[1].ToString(); if (!fileNameIDs.ContainsKey(str)) fileNameIDs.Add(str, id); } } } Device.BeginInvokeOnMainThread(() => { addViewDocsBtn.IsEnabled = true; documentsLbl.Text = "Documents (" + fileNameIDs.Count + ")"; }); }); base.OnAppearing(); } async void ExitBtn_Clicked(object sender, EventArgs e) { if (newEmpQualificationSaved) { CoreTable table = new Client().Query ( new Filter(x => x.EntityLink.ID).IsEqualTo(EmpQualification.ID), new Columns(x => x.ID, x => x.DocumentLink.ID) ); if (table.Rows.Any()) { string chosenOption = await DisplayActionSheet("Alert", "You are exiting without saving. Continue?", null, "Yes", "No"); switch (chosenOption) { case "Cancel": return; default: return; case "Yes": using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Working")) { List empdocs = new List(); List docs = new List(); foreach (CoreRow row in table.Rows) { EmployeeQualificationDocument empdoc = new EmployeeQualificationDocument(); empdoc.ID = Guid.Parse(row.Values[0].ToString()); empdocs.Add(empdoc); Document doc = new Document(); doc.ID = Guid.Parse(row.Values[1].ToString()); docs.Add(doc); } new Client().Delete(empdocs, "Deleted from mobile device"); new Client().Delete(docs, "Deleted from mobile device"); } break; case "No": return; } } new Client().Delete(EmpQualification, "Deleted from mobile device"); } Navigation.PopAsync(); } async void Save_Clicked(object sender, EventArgs e) { if (qualificationPicker.SelectedIndex == -1) { DisplayAlert("Alert", "Choose a qualification first", "OK"); return; } using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving")) { EmpQualification.Employee.ID = App.Data.Me.ID; if (!string.IsNullOrWhiteSpace(frontPhotoDoc.FileName)) { new Client().Save(frontPhotoDoc, "Saved from mobile device"); EmpQualification.FrontPhoto.ID = frontPhotoDoc.ID; EmpQualification.Verified = DateTime.MinValue; } if (!string.IsNullOrWhiteSpace(backPhotoDoc.FileName)) { new Client().Save(backPhotoDoc, "Saved from mobile device"); EmpQualification.BackPhoto.ID = backPhotoDoc.ID; EmpQualification.Verified = DateTime.MinValue; } if (EmpQualification.Qualified == DateTime.MinValue) EmpQualification.Qualified = qualifiedDatePicker.Date; if (EmpQualification.Expiry == DateTime.MinValue) EmpQualification.Expiry = expiryDatePicker.Date; new Client().Save(EmpQualification, "Saved from mobile device"); } await DisplayAlert("Succes", "Qualification saved for " + EmpQualification.Qualification.Description + ". This qualification is now awaiting verification.", "OK"); Navigation.PopAsync(); } #endregion #region Loading async void LoadScreen(Guid id) { try { if (id == Guid.Empty) { qualificationPicker.IsEnabled = true; } else { qualificationPicker.IsEnabled = false; descriptionFrame.BorderColor = Color.Gray; CoreTable table = new Client().Query(new Filter(x => x.ID).IsEqualTo(id), new Columns(x => x.ID, x => x.Qualification.ID, x => x.Qualification.Description, x => x.Expiry, x => x.Qualified, x => x.Verified, x => x.FrontPhoto.ID, x => x.BackPhoto.ID, x => x.Employee.ID, x => x.Qualification.Renewal, x => x.Qualification.Period)); if (table.Rows.Any()) { EmpQualification = table.Rows.FirstOrDefault().ToObject(); } else { Device.BeginInvokeOnMainThread(() => { DisplayAlert("Error loading qualification", "", "OK"); }); return; } if (EmpQualification.Qualified != DateTime.MinValue) { Device.BeginInvokeOnMainThread(() => { qualifiedDatePicker.Date = EmpQualification.Qualified; }); } if (EmpQualification.Expiry != DateTime.MinValue) { Device.BeginInvokeOnMainThread(() => { expiryDatePicker.Date = EmpQualification.Expiry; }); } } RefreshPhotoButtons(); LoadQualifications(); Task.Run(() => { Thread.Sleep(1000); bFirstLoad = false; }); } catch { } } void LoadQualifications() { try { Task.Run(() => { CoreTable table = new Client().Query(null, new Columns(x => x.ID, x => x.Description, x => x.Renewal, x => x.Period) ); foreach (CoreRow row in table.Rows) { Qualification qualification = row.ToObject(); if (!descriptionQualifications.ContainsKey(qualification.Description)) { descriptionQualifications.Add(qualification.Description, qualification); } } Device.BeginInvokeOnMainThread(() => { qualificationPicker.ItemsSource = descriptionQualifications.Keys.ToList(); if (EmpQualification.Qualification.ID != Guid.Empty) { qualificationPicker.SelectedIndex = descriptionQualifications.Keys.ToList().FindIndex(x => x.Equals(EmpQualification.Qualification.Description)); ShowRenewal(); } }); }); } catch { } } void ShowRenewal() { if (EmpQualification.Qualification.Renewal.Equals(QualificationRenewal.Permanent) || EmpQualification.Qualification.Renewal.Equals(QualificationRenewal.Manual)) { renewalLbl.Text = EmpQualification.Qualification.Renewal.ToString(); } else { renewalLbl.Text = EmpQualification.Qualification.Period.ToString() + " " + EmpQualification.Qualification.Renewal; } if (EmpQualification.Qualification.Renewal.Equals(QualificationRenewal.Permanent)) { EmpQualification.Expiry = DateTime.MaxValue; expiryDatePicker.Date = DateTime.MaxValue; expiryDatePicker.IsEnabled = false; Task.Run(() => { Device.BeginInvokeOnMainThread(() => { expiryDatePicker.BackgroundColor = Color.LightGreen; expiryDatePicker.Date = EmpQualification.Expiry; }); Thread.Sleep(1200); Device.BeginInvokeOnMainThread(() => { expiryDatePicker.BackgroundColor = Color.Default; }); }); } else { expiryDatePicker.IsEnabled = true; if (EmpQualification.Expiry != DateTime.MinValue) { expiryDatePicker.Date = EmpQualification.Expiry; } else { EmpQualification.Expiry = DateTime.Today; } } } #endregion #region Response to fields changing / Taps async void AddViewDocsBtn_Clicked(object sender, EventArgs e) { if (qualificationPicker.SelectedIndex == -1) { DisplayAlert("Error", "Select a qualification first", "OK"); return; } using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Loading")) { if (EmpQualification.ID == Guid.Empty) { new Client().Save(EmpQualification, "Saved from mobile device"); newEmpQualificationSaved = true; } PDFList pdfList = new PDFList(); //fileNameIDs, EmpQualification, true, true, true, false); Navigation.PushAsync(pdfList); } } void QualificationPicker_IndexChanged(object sender, EventArgs e) { if (!bFirstLoad) { EmpQualification.Qualification.ID = descriptionQualifications[qualificationPicker.SelectedItem.ToString()].ID; EmpQualification.Qualification.Description = qualificationPicker.SelectedItem.ToString(); EmpQualification.Qualification.Renewal = descriptionQualifications[qualificationPicker.SelectedItem.ToString()].Renewal; EmpQualification.Qualification.Period = descriptionQualifications[qualificationPicker.SelectedItem.ToString()].Period; ShowRenewal(); } } void QualifiedDatePicker_Selected(object sender, DateChangedEventArgs e) { if (!bFirstLoad) { EmpQualification.Qualified = qualifiedDatePicker.Date; EmpQualification.Verified = DateTime.MinValue; Task.Run(() => { Thread.Sleep(300); Device.BeginInvokeOnMainThread(() => { expiryDatePicker.BackgroundColor = Color.LightGreen; expiryDatePicker.Date = EmpQualification.Expiry; }); Thread.Sleep(1200); Device.BeginInvokeOnMainThread(() => { expiryDatePicker.BackgroundColor = Color.Default; }); }); } } void ExpiryDatePicker_Selected(object sender, DateChangedEventArgs e) { if (!bFirstLoad) { EmpQualification.Expiry = expiryDatePicker.Date; EmpQualification.Verified = DateTime.MinValue; } } #endregion #region Photos void TakeFrontPhoto_Clicked(object sender, EventArgs e) { photoType = PhotoType.FrontPhoto; OpenCamera(); } void TakeBackPhoto_Clicked(object sender, EventArgs e) { photoType = PhotoType.BackPhoto; OpenCamera(); } private async void OpenCamera() { try { await CrossMedia.Current.Initialize(); if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported) { return; } String filename = String.Format("{0:yyyy-MM-dd HH:mm:ss.fff}.png", DateTime.Now); var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions { Name = filename, CompressionQuality = 40, PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full, SaveMetaData = false }); if (file == null) return; AddPhoto(file); } catch { } } private async void AddPhoto(Plugin.Media.Abstractions.MediaFile file) { try { using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo")) { var memoryStream = new MemoryStream(); file.GetStream().CopyTo(memoryStream); var data = memoryStream.ToArray(); Document doc = new Document() { FileName = Path.GetFileName(file.Path), Data = data, CRC = CoreUtils.CalculateCRC(data), TimeStamp = DateTime.Now }; if (photoType.Equals(PhotoType.FrontPhoto)) frontPhotoDoc = doc; else if (photoType.Equals(PhotoType.BackPhoto)) backPhotoDoc = doc; RefreshPhotoButtons(); DisplayAlert("Success", "Photo added. Save to complete the process. This photo is not saved to or available on your device", "OK"); } } catch { } } void RefreshPhotoButtons() { Device.BeginInvokeOnMainThread(() => { if (EmpQualification.FrontPhoto.ID != Guid.Empty || !string.IsNullOrWhiteSpace(frontPhotoDoc.FileName)) { TakeFrontPhotoBtn.Text = "Photo added"; TakeFrontPhotoBtn.BackgroundColor = Color.FromHex("#15C7C1"); } else { TakeFrontPhotoBtn.Text = "No photo added"; TakeFrontPhotoBtn.BackgroundColor = Color.Orange; } if (EmpQualification.BackPhoto.ID != Guid.Empty || !string.IsNullOrWhiteSpace(backPhotoDoc.FileName)) { TakeBackPhotoBtn.Text = "Photo added"; TakeBackPhotoBtn.BackgroundColor = Color.FromHex("#15C7C1"); } else { TakeBackPhotoBtn.Text = "No photo added"; TakeBackPhotoBtn.BackgroundColor = Color.Orange; } }); } #endregion #region Utils private void OnTap(object sender, EventArgs e) { ImageViewer viewer = new ImageViewer((sender as Image).Source); Navigation.PushAsync(viewer); } enum PhotoType { FrontPhoto, BackPhoto, Default } #endregion } }