using Comal.Classes; using InABox.Clients; using InABox.Core; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; using Xamarin.Essentials; using Xamarin.Forms; using Xamarin.Forms.Xaml; using XF.Material.Forms.UI.Dialogs; namespace PRS.Mobile { public delegate void ConsignmentSavedEvent(); [XamlCompilation(XamlCompilationOptions.Compile)] public partial class ConsignmentCompletionPage { public event ConsignmentSavedEvent OnConsignmentSaved; List listReceived = new List(); int shortSupplyIssues = 0; int extraSupplyIssues = 0; int count = 1; Guid consignmentID = Guid.Empty; string consignmentNumber = ""; Dictionary imagesDocuments = new Dictionary(); public ConsignmentCompletionPage(List _listReceived, Guid _consignmentID, string _consignmentNumber) { InitializeComponent(); consignmentID = _consignmentID; consignmentNumber = _consignmentNumber; listReceived = _listReceived; LoadScreen(); } private void LoadScreen() { try { titleLbl.Text = "Consignment " + consignmentNumber; totalReceivedNumberLbl.Text = listReceived.Count.ToString(); string text = new Client().Query( new Filter(x => x.ID).IsEqualTo(consignmentID), new Columns(ColumnTypeFlags.None).Add(x => x.Description) ).Rows.FirstOrDefault().Values[0].ToString(); List issuesList = new List(); foreach (POItemShell item in listReceived) { if (item.Description.Contains("due to short supply")) { shortSupplyIssues++; issuesList.Add(item); } else if (item.Description.Contains("Purchase Order Item Line split due to extra")) { extraSupplyIssues++; issuesList.Add(item); } } if (issuesList.Count > 0) { foreach (POItemShell item in issuesList) { if (item.Description.Contains("due to short supply")) { text = text + System.Environment.NewLine + count + ". " + item.Description; count++; } else if (item.Description.Contains("Purchase Order Item Line split due to extra")) { text = text + System.Environment.NewLine + count + ". " + item.Description; count++; } } } descriptionLbl.Text = text; } catch { } } async void TakePhoto_Clicked(object sender, EventArgs e) { TakeAPhoto(); } async void ChooseImage_Clicked(object sender, EventArgs e) { ChooseAPhoto(); } private async void ConfirmBtn_Clicked(object sender, EventArgs e) { try { if (photosFrame.BorderColor == Color.Red) { return; } else { using (await MaterialDialog.Instance.LoadingDialogAsync(message: "Saving")) { Consignment consignment = new Consignment() { ID = consignmentID, Number = consignmentNumber }; consignment.ActualWarehouseArrival = DateTime.Now; consignment.Description = descriptionLbl.Text; consignment.Employee.ID = App.Data.Me.ID; SaveConsignment(consignment); await DisplayAlert("Success", "Receival saved for " + consignmentNumber, "OK"); OnConsignmentSaved?.Invoke(); } Navigation.PopAsync(); } } catch (Exception ex) { OnConsignmentSaved?.Invoke(); } } private void SaveConsignment(Consignment consignment) { try { new Client().Save(consignment, "Updated from mobile device"); } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); SaveConsignment(consignment); } } //Note that photos are saved as they are taken, to avoid saving a long list of photos which some devices can't handle //PurchaseOrderDocuments, StockMovementBatch and StockMovementBatchDocuments are saved in ConsignmentStore #region Photos private async void TakeAPhoto() { try { 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 = 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 }); doc = SavePhoto(doc); SaveConsignmentDocument(doc.ID); imagesDocuments.Add(img, doc); //file.Dispose(); if (img != null) { Device.BeginInvokeOnMainThread(() => { ImageScroller.IsVisible = true; images.Children.Add(img); UpdateColours(); }); } } } catch (Exception ex) { DisplayAlert("Error saving - please try again", ex.Message, "OK"); } } private Document SavePhoto(Document doc) { try { new Client().Save(doc, "Saved on Mobile Receivals Module"); return doc; } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); return SavePhoto(doc); } } private async void ChooseAPhoto() { try { 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 }); doc = SavePhoto(doc); SaveConsignmentDocument(doc.ID); imagesDocuments.Add(img, doc); //file.Dispose(); if (img != null) { Device.BeginInvokeOnMainThread(() => { ImageScroller.IsVisible = true; images.Children.Add(img); UpdateColours(); }); } } } catch (Exception ex) { DisplayAlert("Error saving - please try again", ex.Message, "OK"); } } private void SaveConsignmentDocument(Guid docid) { Task.Run(() => { try { ConsignmentDocument consignmentDocument = new ConsignmentDocument(); consignmentDocument.DocumentLink.ID = docid; consignmentDocument.EntityLink.ID = consignmentID; new Client().Save(consignmentDocument, "Saved on Mobile Receivals Module"); } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); SaveConsignmentDocument(docid); } }); } private void OnTap(object obj) { try { ImageViewerPage viewer = new ImageViewerPage(obj as ImageSource, () => DeleteImage(obj)); Navigation.PushAsync(viewer); } catch { } } private void DeleteImage(object obj) { Image img = imagesDocuments.Keys.FirstOrDefault(x => x.Source.Equals(obj as ImageSource)); DeleteDocuments(imagesDocuments[img].ID); imagesDocuments.Remove(img); Device.BeginInvokeOnMainThread(() => { images.Children.Clear(); if (imagesDocuments.Count > 0) { foreach (Image image in imagesDocuments.Keys) { images.Children.Add(image); } } UpdateColours(); }); } private void DeleteDocuments(Guid docid) { Task.Run(() => { try { Document doc = new Document { ID = docid }; new Client().Delete(doc, "User removed unwanted photo on mobile receivals module"); CoreTable table = new Client().Query(new Filter(x => x.DocumentLink.ID).IsEqualTo(docid), new Columns(ColumnTypeFlags.None).Add(x => x.ID)); if (table.Rows.Any()) { ConsignmentDocument consignmentDocument = table.Rows.FirstOrDefault().ToObject(); new Client().Delete(consignmentDocument, "User removed unwanted photo on mobile receivals module"); } } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); DeleteDocuments(docid); } }); } #endregion private void UpdateColours() { if (imagesDocuments.Count > 0) photosFrame.BorderColor = Color.Gray; else photosFrame.BorderColor = Color.Red; } } }