|
@@ -1,31 +1,162 @@
|
|
|
+using System;
|
|
|
+using System.IO;
|
|
|
+using System.Linq;
|
|
|
using System.Threading.Tasks;
|
|
|
using Avalonia.Controls;
|
|
|
using Avalonia.Media;
|
|
|
+using Comal.Classes;
|
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
using InABox.Avalonia;
|
|
|
+using InABox.Avalonia.Components;
|
|
|
+using InABox.Avalonia.Platform;
|
|
|
+using InABox.Clients;
|
|
|
+using InABox.Core;
|
|
|
+using PRS.Avalonia.Components;
|
|
|
|
|
|
namespace PRS.Avalonia.Modules;
|
|
|
|
|
|
public partial class DocumentScannerViewModel : ModuleViewModel
|
|
|
{
|
|
|
public override string Title => "Doc Scanner";
|
|
|
-
|
|
|
- [ObservableProperty] private IImage? _imageSource;
|
|
|
|
|
|
- [ObservableProperty] private bool _active;
|
|
|
+ [ObservableProperty]
|
|
|
+ private DataEntryDocumentModel _documents;
|
|
|
+
|
|
|
+ [ObservableProperty]
|
|
|
+ private DataEntryTagModel _tags;
|
|
|
|
|
|
+ public DocumentScannerViewModel()
|
|
|
+ {
|
|
|
+ Documents = new(DataAccess,
|
|
|
+ () => new Filter<DataEntryDocument>(x => x.Employee.ID).IsEqualTo(Repositories.Me.ID)
|
|
|
+ .And(x => x.Archived).IsEqualTo(DateTime.MinValue),
|
|
|
+ () => DefaultCacheFileName<DataEntryDocumentShell>());
|
|
|
+
|
|
|
+ Tags = new(DataAccess,
|
|
|
+ () => new Filter<DataEntryTag>().All(),
|
|
|
+ () => DefaultCacheFileName<DataEntryTagShell>());
|
|
|
+
|
|
|
+ PrimaryMenu.Add(new AvaloniaMenuItem(Images.plus, () =>
|
|
|
+ {
|
|
|
+ var menu = new CoreMenu<IImage>();
|
|
|
+
|
|
|
+ menu.AddItem("Take Photo", TakePhoto);
|
|
|
+ menu.AddItem("Browse Library", BrowseLibrary);
|
|
|
+
|
|
|
+ return menu;
|
|
|
+ }));
|
|
|
+
|
|
|
+ ProgressVisible = true;
|
|
|
+ }
|
|
|
+
|
|
|
+ protected override async Task<TimeSpan> OnRefresh()
|
|
|
+ {
|
|
|
+ await Task.WhenAll(Documents.RefreshAsync(false), Tags.RefreshAsync(false));
|
|
|
+
|
|
|
+ ProgressVisible = false;
|
|
|
+
|
|
|
+ return TimeSpan.Zero;
|
|
|
+ }
|
|
|
+
|
|
|
[RelayCommand]
|
|
|
- private async Task ToggleCamera(Button button)
|
|
|
+ private void Click(DataEntryDocumentShell shell)
|
|
|
+ {
|
|
|
+ Navigation.Navigate<DocumentScannerEditorViewModel>(model =>
|
|
|
+ {
|
|
|
+ model.DataEntryDocument = shell;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<bool> AddImage<T, TOptions>(TOptions options)
|
|
|
+ where T : MobileDocumentSource
|
|
|
+ where TOptions : MobileImageOptions<T>
|
|
|
{
|
|
|
- if (Active)
|
|
|
+ MobileDocument? file = null;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ file = await MobileDocument.From(App.TopLevel, options);
|
|
|
+ }
|
|
|
+ catch(Exception e)
|
|
|
{
|
|
|
- Active = false;
|
|
|
+ MobileLogging.LogExceptionMessage(e);
|
|
|
+ await MessageDialog.ShowError(e);
|
|
|
}
|
|
|
- else
|
|
|
+
|
|
|
+ if (file is null) return false;
|
|
|
+
|
|
|
+ if(file.Data.Length == 0)
|
|
|
{
|
|
|
- Active = true;
|
|
|
+ await MessageDialog.ShowMessage("The selected file was empty. No document created.");
|
|
|
+ return false;
|
|
|
}
|
|
|
- var doc = await MobileDocument.From(App.TopLevel, new MobileDocumentCameraOptions());
|
|
|
+
|
|
|
+ var extension = Path.GetExtension(file.FileName);
|
|
|
+ file.FileName = Path.ChangeExtension(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), extension);
|
|
|
+
|
|
|
+ var shell = Documents.CreateItem();
|
|
|
+ if(await ConfirmScan(shell))
|
|
|
+ {
|
|
|
+ shell.Thumbnail = PlatformTools.ImageTools.CreateThumbnail(file.Data, 256, 256);
|
|
|
+ shell.FileName = file.FileName;
|
|
|
+
|
|
|
+ ProgressVisible = true;
|
|
|
+
|
|
|
+ var document = new Document
|
|
|
+ {
|
|
|
+ FileName = file.FileName,
|
|
|
+ Data = file.Data,
|
|
|
+ CRC = CoreUtils.CalculateCRC(file.Data),
|
|
|
+ TimeStamp = DateTime.Now
|
|
|
+ };
|
|
|
+ await Client.SaveAsync(document, "Created on Mobile Device");
|
|
|
+
|
|
|
+ shell.DocumentID = document.ID;
|
|
|
+ await shell.SaveAsync("Created on Mobile Device");
|
|
|
+
|
|
|
+ Documents.CommitItem(shell);
|
|
|
+
|
|
|
+ ProgressVisible = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<bool> ConfirmScan(DataEntryDocumentShell shell)
|
|
|
+ {
|
|
|
+ shell.EmployeeID = Repositories.Me.ID;
|
|
|
+ if(Tags.ItemCount == 0)
|
|
|
+ {
|
|
|
+ shell.TagID = Guid.Empty;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ var tags = await SelectionViewModel.ExecutePopup<DataEntryTagShell>(model =>
|
|
|
+ {
|
|
|
+ model.CanRefresh = false;
|
|
|
+ model.SelectionTitle = "Choose Tag";
|
|
|
+ model.Columns.Add(new AvaloniaDataGridTextColumn<DataEntryTagShell>
|
|
|
+ {
|
|
|
+ Column = x => x.Name,
|
|
|
+ Caption = "Tag",
|
|
|
+ Width = GridLength.Star
|
|
|
+ });
|
|
|
+ }, (args) => Tags);
|
|
|
+ if (tags is null || tags.FirstOrDefault() is not DataEntryTagShell tag) return false;
|
|
|
+ shell.TagID = tag.ID;
|
|
|
+ shell.TagName = tag.Name;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<bool> BrowseLibrary()
|
|
|
+ {
|
|
|
+ await AddImage<MobileDocumentPhotoLibrarySource, MobileDocumentPhotoLibraryOptions>(PhotoUtils.CreatePhotoLibraryOptions());
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ private async Task<bool> TakePhoto()
|
|
|
+ {
|
|
|
+ await AddImage<MobileDocumentCameraSource, MobileDocumentCameraOptions>(PhotoUtils.CreateCameraOptions());
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|