using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Xamarin.Essentials; using Xamarin.Forms; using ZXing; using ZXing; using Xamarin.Forms; using Xamarin.Forms.Xaml; using comal.timesheets.CustomControls; using Comal.Classes; using InABox.Core; using InABox.Clients; using System.Threading; using Plugin.Media; using XF.Material.Forms.UI.Dialogs; using System.IO; namespace comal.timesheets.StoreRequis { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class StoreRequiConfirmationPage : ContentPage { #region Fields public delegate void SaveSelectedEvent(); public event SaveSelectedEvent OnSaveSelected; JobShell job = new JobShell(); bool newRequi; Requisition requisition; bool isNewRequest = false; Dictionary imagesDocuments = new Dictionary(); List requiItems = new List(); List oldrequiitems = new List(); #endregion #region Constructor and appearing public StoreRequiConfirmationPage(Requisition _requisition, List _requiitems, List _oldrequiitems) //requi could be existing or a blank/new requi (ID empty) { InitializeComponent(); requiItems = _requiitems; if (requiItems[0].IsNotes == true) { requiItems.RemoveAt(0); } oldrequiitems = _oldrequiitems; requiStatusLbl.IsVisible = true; requiStatusFrame.IsVisible = true; boxesLbl.IsVisible = true; boxesQtyFrame.IsVisible = true; photosLbl.IsVisible = true; photosFrame.IsVisible = true; if (_requisition.ID != Guid.Empty) forDeliveryRb.IsChecked = true; else takenNowRb.IsChecked = true; dueLbl.IsVisible = false; dueFrame.IsVisible = false; ChooseTrack(_requisition); } public StoreRequiConfirmationPage() //when no requi is passed, app is creating a new requi request { InitializeComponent(); isNewRequest = true; NewRequiTrack(); UpdateColours(); notesTitleLbl.Text = "Request"; dueDatePckr.IsEnabled = true; reduceQtyBtn.IsEnabled = false; increaseQtyBtn.IsEnabled = false; TakePhoto.IsEnabled = false; ChooseImage.IsEnabled = false; } private void ChooseTrack(Requisition _requisition) { if (_requisition.ID == Guid.Empty) { NewRequiTrack(); } else { ExistingRequiTrack(_requisition); } } private void NewRequiTrack() { newRequi = true; requisition = new Requisition(); requisition.Title = "New Requisition"; requisition.Boxes = 1; boxQtyLbl.Text = requisition.Boxes.ToString(); titleLbl.Text = "New Requisition"; requisition.Title = "New Requisition"; requisition.Due = DateTime.Now; requisition.RequestedBy.ID = GlobalVariables.EmpID; requisition.RequestedBy.Name = GlobalVariables.EmpName; //create new requi } private void ExistingRequiTrack(Requisition _requisition) { newRequi = false; requisition = _requisition; titleLbl.Text = "Requi " + _requisition.Number.ToString(); LoadPhotos(); UpdateScreen(); } #endregion #region Screen Update private void UpdateScreen() { jobLbl.Text = requisition.JobLink.JobNumber + " " + requisition.JobLink.Name; boxQtyLbl.Text = requisition.Boxes.ToString(); if (string.IsNullOrEmpty(notesEdt.Text)) { List notes = new List(); foreach (string s in requisition.Notes) { string substring = s.Replace("=", string.Empty); substring = substring.Trim(); if (!string.IsNullOrWhiteSpace(substring)) notes.Add(substring); } notesEdt.Text = String.Join("\n", notes); } UpdateColours(); } private void UpdateColours() { if (requisition.JobLink.ID == Guid.Empty) jobFrame.BorderColor = Color.Red; else jobFrame.BorderColor = Color.Gray; if (images.Children.Count == 0) photosFrame.BorderColor = Color.Red; else photosFrame.BorderColor = Color.Gray; if (isNewRequest) photosFrame.BorderColor = Color.Gray; } private void LoadPhotos() { if (requisition.Documents != 0) { var table = new Client().Query( new Filter(x => x.EntityLink.ID).IsEqualTo(requisition.ID), new Columns(x => x.DocumentLink.ID), null ); if (table.Rows.Count != 0) { foreach (var row in table.Rows) { List list = row.Values; if (list[0] == null) { list[0] = Guid.Empty; } Guid requisitionDocLinkID = Guid.Parse(list[0].ToString()); new Client().Query( new Filter(x => x.ID).IsEqualTo(requisitionDocLinkID), null, null, (t, e) => { CoreRow docrow = t.Rows.FirstOrDefault(); if (docrow != null) { byte[] data = docrow.Get(x => x.Data); ImageSource src = ImageSource.FromStream(() => new MemoryStream(data)); Image img = new Image(); img.HeightRequest = 150; img.WidthRequest = 150; img.Aspect = Aspect.AspectFit; img.Source = src; img.GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(OnTap), CommandParameter = src, NumberOfTapsRequired = 1 }); Device.BeginInvokeOnMainThread(() => { ImageScroller.IsVisible = true; images.Children.Add(img); UpdateColours(); }); } } ); } } } } #endregion #region Selection private void SelectJobBtn_Clicked(object sender, EventArgs e) { JobSelectionPage jobSelectionPage = new JobSelectionPage(); jobSelectionPage.OnItemSelected += (() => { requisition.JobLink.ID = jobSelectionPage.Job.ID; requisition.JobLink.Name = jobSelectionPage.Job.Name; requisition.JobLink.JobNumber = jobSelectionPage.Job.JobNumber; UpdateScreen(); }); Navigation.PushAsync(jobSelectionPage); } private void ReduceQtyBtn_Clicked(object sender, EventArgs e) { if (requisition.Boxes <= 1) return; else { requisition.Boxes--; UpdateScreen(); } } private void IncreaseQtyBtn_Clicked(object sender, EventArgs e) { requisition.Boxes++; UpdateScreen(); } private void DueDatePckr_DateSelected(object sender, EventArgs e) { requisition.Due = dueDatePckr.Date; } #endregion #region Photos private void TakePhoto_Clicked(object sender, EventArgs e) { TakeAPhoto(); } private void ChooseImage_Clicked(object sender, EventArgs e) { ChooseAPhoto(); } private async void TakeAPhoto() { await CrossMedia.Current.Initialize(); if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported) { await DisplayAlert("No Camera", ":( No camera available.", "OK"); 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 = 10, PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full }); if (file == null) return; using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo")) { Image img = null; var memoryStream = new MemoryStream(); file.GetStream().CopyTo(memoryStream); var data = memoryStream.ToArray(); Document doc = new Document() { FileName = filename, Data = data, CRC = CoreUtils.CalculateCRC(data), TimeStamp = DateTime.Now }; ImageSource src = ImageSource.FromStream(() => new MemoryStream(data)); img = new Image(); img.HeightRequest = 150; img.WidthRequest = 150; img.Aspect = Aspect.AspectFit; img.Source = src; img.GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(OnTap), CommandParameter = src, NumberOfTapsRequired = 1 }); imagesDocuments.Add(img, doc); file.Dispose(); if (img != null) { Device.BeginInvokeOnMainThread(() => { ImageScroller.IsVisible = true; images.Children.Add(img); UpdateColours(); }); } } } private async void ChooseAPhoto() { await CrossMedia.Current.Initialize(); if (!CrossMedia.Current.IsPickPhotoSupported) { await DisplayAlert("No Library", ":( No Photo Library available.", "OK"); return; } var file = await CrossMedia.Current.PickPhotoAsync(new Plugin.Media.Abstractions.PickMediaOptions() { CompressionQuality = 10, PhotoSize = Plugin.Media.Abstractions.PhotoSize.Full }); if (file == null) return; using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo")) { Image img = null; 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 }; ImageSource src = ImageSource.FromStream(() => new MemoryStream(data)); img = new Image(); img.HeightRequest = 150; img.WidthRequest = 150; img.Aspect = Aspect.AspectFit; img.Source = src; img.GestureRecognizers.Add(new TapGestureRecognizer { Command = new Command(OnTap), CommandParameter = src, NumberOfTapsRequired = 1 }); imagesDocuments.Add(img, doc); file.Dispose(); if (img != null) { Device.BeginInvokeOnMainThread(() => { ImageScroller.IsVisible = true; images.Children.Add(img); UpdateColours(); }); } } } private void OnTap(object obj) { ImageViewer viewer = new ImageViewer(obj as ImageSource); Navigation.PushAsync(viewer); viewer.ChooseDelete(); viewer.OnDeleteSelected += () => { Image img = imagesDocuments.Keys.First(x => x.Source.Equals(obj as ImageSource)); imagesDocuments.Remove(img); Device.BeginInvokeOnMainThread(() => { images.Children.Clear(); if (imagesDocuments.Count > 0) { foreach (Image image in imagesDocuments.Keys) { images.Children.Add(image); } } UpdateColours(); }); }; } #endregion #region Save private async void SaveBtn_Clicked(object sender, EventArgs e) { if (CheckSaveOk()) { if (isNewRequest) { requisition.Request = notesEdt.Text; new Client().Save(requisition, "Created on Mobile Device"); DisplayAlert("Success", "Requisition " + requisition.Number + " Created", "Ok"); } else { if (takenNowRb.IsChecked) { requisition.TakenBy.ID = GlobalVariables.EmpID; requisition.TakenBy.Name = GlobalVariables.EmpName; } using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving")) { SaveRequi(); } if (requisition.ID != Guid.Empty) { using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving")) { SavePhotos(); SaveItems(); } await DisplayAlert("Success", "Requisition " + requisition.Number + " Saved", "Ok"); OnSaveSelected?.Invoke(); Navigation.PopAsync(); } } } } private void SaveRequi() { requisition.Filled = DateTime.Now; requisition.Notes = new string[] { notesEdt.Text }; new Client().Save(requisition, "Saved requi on mobile device"); } private async void SaveItems() { Task.Run(() => { List toDelete = new List(); if (oldrequiitems.Count > 0) { foreach (StoreRequiItemShell oldshell in oldrequiitems) { StoreRequiItemShell shell = requiItems.Find(x => x.ID.Equals(oldshell.ID)); if (shell == null) { toDelete.Add(new RequisitionItem { ID = oldshell.ID }); } } if (toDelete.Count > 0) { new Client().Delete(toDelete, "Updated from mobile device"); } } }); List toSave = new List(); foreach (StoreRequiItemShell itemShell in requiItems) { RequisitionItem item = new RequisitionItem(); item.RequisitionLink.ID = requisition.ID; item.ID = itemShell.ID; item.Product.ID = itemShell.ProductID; item.Product.Code = itemShell.ProductCode; item.Product.Name = itemShell.ProductName; item.Location.ID = itemShell.HoldingID; item.Quantity = itemShell.Quantity; item.Description = item.Product.Name; item.Code = item.Product.Code; toSave.Add(item); } new Client().Save(toSave, "Saved requi on mobile device"); } private async void SavePhotos() { Task.Run(() => { if (imagesDocuments.Count != 0) { new Client().Save(imagesDocuments.Values, "Photo Taken on Mobile device Requis module"); List newRequiDocuments = new List(); foreach (Document doc in imagesDocuments.Values) { var requiDocument = new RequisitionDocument(); requiDocument.EntityLink.ID = requisition.ID; requiDocument.DocumentLink.ID = doc.ID; requiDocument.DocumentLink.FileName = doc.FileName; newRequiDocuments.Add(requiDocument); } new Client().Save(newRequiDocuments, "Photo Taken on Mobile device Requis module"); } }); } private bool CheckSaveOk() { bool bOK = false; if (requisition.JobLink.ID != Guid.Empty) { bOK = true; } else { DisplayAlert("Unable to save", "Add a Job", "OK"); return bOK; } if (images.Children.Count > 0) { bOK = true; } else if (isNewRequest) { bOK = true; } else { bOK = false; DisplayAlert("Unable to save", "Add a Photo", "OK"); return bOK; } return bOK; } #endregion } }