SubmitDocsViewModel.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. using System;
  2. using System.IO;
  3. using System.Linq;
  4. using System.Threading.Tasks;
  5. using Avalonia.Controls;
  6. using Avalonia.Media;
  7. using Comal.Classes;
  8. using CommunityToolkit.Mvvm.ComponentModel;
  9. using CommunityToolkit.Mvvm.Input;
  10. using InABox.Avalonia;
  11. using InABox.Avalonia.Components;
  12. using InABox.Avalonia.Dialogs;
  13. using InABox.Avalonia.Platform;
  14. using InABox.Clients;
  15. using InABox.Core;
  16. using PRS.Avalonia.Components;
  17. namespace PRS.Avalonia.Modules;
  18. public partial class SubmitDocsViewModel : ModuleViewModel
  19. {
  20. public override string Title => "Submit Docs";
  21. [ObservableProperty]
  22. private DataEntryDocumentModel _documents;
  23. [ObservableProperty]
  24. private DataEntryTagModel _tags;
  25. public SubmitDocsViewModel()
  26. {
  27. Documents = new(DataAccess,
  28. () => new Filter<DataEntryDocument>(x => x.Employee.ID).IsEqualTo(Repositories.Me.ID)
  29. .And(x => x.Archived).IsEqualTo(DateTime.MinValue),
  30. () => DefaultCacheFileName<DataEntryDocumentShell>());
  31. Tags = new(DataAccess,
  32. () => new Filter<DataEntryTag>().All(),
  33. () => DefaultCacheFileName<DataEntryTagShell>());
  34. PrimaryMenu.Add(new AvaloniaMenuItem(Images.plus, () =>
  35. {
  36. var menu = new CoreMenu<IImage>();
  37. menu.AddItem("Take Photo", TakePhoto);
  38. menu.AddItem("Browse Library", BrowseLibrary);
  39. return menu;
  40. }));
  41. ProgressVisible = true;
  42. }
  43. protected override async Task<TimeSpan> OnRefresh()
  44. {
  45. await Task.WhenAll(Documents.RefreshAsync(false), Tags.RefreshAsync(false));
  46. ProgressVisible = false;
  47. return TimeSpan.Zero;
  48. }
  49. [RelayCommand]
  50. private void Click(DataEntryDocumentShell shell)
  51. {
  52. Navigation.Navigate<SubmitDocsEditorViewModel>(model =>
  53. {
  54. model.DataEntryDocument = shell;
  55. });
  56. }
  57. private async Task<bool> AddImage<T, TOptions>(TOptions options)
  58. where T : MobileDocumentSource
  59. where TOptions : MobileImageOptions<T>
  60. {
  61. MobileDocument? file = null;
  62. try
  63. {
  64. file = await MobileDocument.From(App.TopLevel, options);
  65. }
  66. catch(Exception e)
  67. {
  68. MobileLogging.LogExceptionMessage(e);
  69. await MessageDialog.ShowError(e);
  70. }
  71. if (file is null) return false;
  72. if(file.Data.Length == 0)
  73. {
  74. await MessageDialog.ShowMessage("The selected file was empty. No document created.");
  75. return false;
  76. }
  77. var extension = Path.GetExtension(file.FileName);
  78. file.FileName = Path.ChangeExtension(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), extension);
  79. var shell = Documents.CreateItem();
  80. if(await ConfirmScan(shell))
  81. {
  82. shell.Thumbnail = PlatformTools.ImageTools.CreateThumbnail(file.Data, 256, 256);
  83. shell.FileName = file.FileName;
  84. ProgressVisible = true;
  85. var document = new Document
  86. {
  87. FileName = file.FileName,
  88. Data = file.Data,
  89. CRC = CoreUtils.CalculateCRC(file.Data),
  90. TimeStamp = DateTime.Now
  91. };
  92. await Client.SaveAsync(document, "Created on Mobile Device");
  93. shell.DocumentID = document.ID;
  94. await shell.SaveAsync("Created on Mobile Device");
  95. ProgressVisible = false;
  96. }
  97. return true;
  98. }
  99. private async Task<bool> ConfirmScan(DataEntryDocumentShell shell)
  100. {
  101. shell.EmployeeID = Repositories.Me.ID;
  102. if(Tags.ItemCount == 0)
  103. {
  104. shell.TagID = Guid.Empty;
  105. return true;
  106. }
  107. var tags = await SelectionViewModel.ExecutePopup<DataEntryTagShell>(model =>
  108. {
  109. model.CanRefresh = false;
  110. model.SelectionTitle = "Choose Tag";
  111. model.Columns.Add(new AvaloniaDataGridTextColumn<DataEntryTagShell>
  112. {
  113. Column = x => x.Name,
  114. Caption = "Tag",
  115. Width = GridLength.Star
  116. });
  117. }, (args) => Tags);
  118. if (tags is null || tags.FirstOrDefault() is not DataEntryTagShell tag) return false;
  119. shell.TagID = tag.ID;
  120. shell.TagName = tag.Name;
  121. return true;
  122. }
  123. private async Task<bool> BrowseLibrary()
  124. {
  125. await AddImage<MobileDocumentPhotoLibrarySource, MobileDocumentPhotoLibraryOptions>(PhotoUtils.CreatePhotoLibraryOptions());
  126. return true;
  127. }
  128. private async Task<bool> TakePhoto()
  129. {
  130. await AddImage<MobileDocumentCameraSource, MobileDocumentCameraOptions>(PhotoUtils.CreateCameraOptions());
  131. return true;
  132. }
  133. }