using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Xamarin.Forms; using Xamarin.Forms.Xaml; using Comal.Classes; using InABox.Core; using InABox.Clients; using XF.Material.Forms.UI.Dialogs; using System.IO; using Xamarin.Essentials; namespace PRS.Mobile { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class StoreRequiConfirmationPage { #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(Comal.Classes.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 = App.Data.Me.ID; requisition.RequestedBy.Name = App.Data.Me.Name; //create new requi } private void ExistingRequiTrack(Comal.Classes.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 = QueryPhotos(); while (table == null) table = QueryPhotos(); 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()); Client.Query( new Filter(x => x.ID).IsEqualTo(requisitionDocLinkID), Columns.All(), 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(); }); } } ); } } } } private CoreTable QueryPhotos() { try { return new Client().Query( new Filter(x => x.EntityLink.ID).IsEqualTo(requisition.ID), new Columns(ColumnTypeFlags.None).Add(x => x.DocumentLink.ID), null ); } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); return null; } } #endregion #region Selection private void SelectJobBtn_Clicked(object sender, EventArgs e) { JobSelectionPage jobSelectionPage = new JobSelectionPage( (job) => { if (job != null) { requisition.JobLink.ID = job.ID; requisition.JobLink.Name = job.Name; requisition.JobLink.JobNumber = 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() { var file = await MediaPicker.CapturePhotoAsync(); if (file == null) return; using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo")) { Image img = null; var memoryStream = new MemoryStream(); using (var stream = await file.OpenReadAsync()) await stream.CopyToAsync(memoryStream); var data = memoryStream.ToArray(); Document doc = new Document() { FileName = Path.GetFileName(file.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); if (img != null) { Device.BeginInvokeOnMainThread(() => { ImageScroller.IsVisible = true; images.Children.Add(img); UpdateColours(); }); } } } private async void ChooseAPhoto() { var file = await MediaPicker.PickPhotoAsync(); if (file == null) return; using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Adding Photo")) { Image img = null; var memoryStream = new MemoryStream(); using (var stream = await file.OpenReadAsync()) await stream.CopyToAsync(memoryStream); var data = memoryStream.ToArray(); Document doc = new Document() { FileName = Path.GetFileName(file.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); if (img != null) { Device.BeginInvokeOnMainThread(() => { ImageScroller.IsVisible = true; images.Children.Add(img); UpdateColours(); }); } } } private void OnTap(object obj) { ImageViewerPage viewer = new ImageViewerPage(obj as ImageSource, () => DeleteImage(obj)); Navigation.PushAsync(viewer); } private void DeleteImage(object obj) { 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; DoSaveRequi(requisition); DisplayAlert("Success", "Requisition " + requisition.Number + " Created", "Ok"); } else { if (takenNowRb.IsChecked) { requisition.TakenBy.ID = App.Data.Me.ID; requisition.TakenBy.Name = App.Data.Me.Name; } 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 Requisition DoSaveRequi(Comal.Classes.Requisition requisition) { try { new Client().Save(requisition, "Created on Mobile Device"); return requisition; } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); return DoSaveRequi(requisition); } } private void SaveRequi() { requisition.Filled = DateTime.Now; requisition.Notes = new string[] { notesEdt.Text }; DoSaveRequi(requisition); } private 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) { DoDeleteRequiItems(toDelete); } } }); List toSave = new List(); foreach (StoreRequiItemShell requiItemShell in requiItems) { RequisitionItem item = new RequisitionItem(); item.RequisitionLink.ID = requisition.ID; item.ID = requiItemShell.ID; item.Product.ID = requiItemShell.ProductID; item.Product.Code = requiItemShell.ProductCode; item.Product.Name = requiItemShell.ProductName; item.Location.ID = requiItemShell.LocationID; item.Quantity = requiItemShell.Quantity; item.Description = requiItemShell.ProductName; item.Code = requiItemShell.ProductCode; item.JobLink.ID = requiItemShell.JobID; item.Style.ID = requiItemShell.StyleID; item.Picked = item.Picked == DateTime.MinValue ? DateTime.Now : item.Picked; item.Dimensions.Unit.ID = requiItemShell.Dimensions.Unit.ID; item.Dimensions.Unit.HasQuantity = requiItemShell.Dimensions.Unit.HasQuantity; item.Dimensions.Unit.HasLength = requiItemShell.Dimensions.Unit.HasLength; item.Dimensions.Unit.HasHeight = requiItemShell.Dimensions.Unit.HasHeight; item.Dimensions.Unit.HasWeight = requiItemShell.Dimensions.Unit.HasWeight; item.Dimensions.Unit.HasWidth = requiItemShell.Dimensions.Unit.HasWidth; item.Dimensions.Quantity = requiItemShell.Dimensions.Quantity; item.Dimensions.Length = requiItemShell.Dimensions.Length; item.Dimensions.Height = requiItemShell.Dimensions.Height; item.Dimensions.Weight = requiItemShell.Dimensions.Weight; item.Dimensions.Width = requiItemShell.Dimensions.Width; item.Dimensions.Unit.Format = requiItemShell.Dimensions.Unit.Format; item.Dimensions.Unit.Formula = requiItemShell.Dimensions.Unit.Formula; item.Dimensions.UnitSize = requiItemShell.Dimensions.UnitSize; toSave.Add(item); } DoSaveRequiItems(toSave); } private void DoDeleteRequiItems(List toDelete) { try { new Client().Delete(toDelete, "Updated from mobile device"); } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); DoDeleteRequiItems(toDelete); } } private void DoSaveRequiItems(List toSave) { try { new Client().Save(toSave, "Saved requi on mobile device"); } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); DoSaveRequiItems(toSave); } } private void SavePhotos() { Task.Run(() => { if (imagesDocuments.Count != 0) { DoSaveDocuments(); 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); } DoSaveRequiDocuments(newRequiDocuments); } }); } private void DoSaveDocuments() { try { new Client().Save(imagesDocuments.Values, "Photo Taken on Mobile device Requis module"); } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); DoSaveDocuments(); } } private void DoSaveRequiDocuments(List newRequiDocuments) { try { new Client().Save(newRequiDocuments, "Photo Taken on Mobile device Requis module"); } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); DoSaveRequiDocuments(newRequiDocuments); } } 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 } }