using System.IO.Compression; using Microsoft.AspNetCore.Components; using Microsoft.FluentUI.AspNetCore.Components; using Schaad.Accounting.Datasets; using Schaad.Accounting.Interfaces; namespace Schaad.Accounting.UI.Components.Pages; public partial class StatementImport : ComponentBase { [Inject] private IFileService fileService { get; set; } = null!; [Inject] private IToastService toastService { get; set; } = null!; [Inject] private IMessageService messageService { get; set; } = null!; /// /// Fires after all uploaded files have been processed, so the parent can /// refresh dependent views (e.g. re-run the auto-matcher on Home). /// [Parameter] public EventCallback OnImported { get; set; } private FluentInputFile? myFileByBuffer; private int? progressPercent; private string? progressTitle; private bool cancelRequested; private Dictionary Files = new(); private async Task OnProgressChangeAsync(FluentInputFileEventArgs file) { progressPercent = file.ProgressPercent; progressTitle = file.ProgressTitle; file.IsCancelled = cancelRequested; if (!Files.ContainsKey(file.Index)) { var localFile = Path.GetTempFileName() + file.Name; Files.Add(file.Index, localFile); } await file.Buffer.AppendToFileAsync(Files[file.Index]); } private async Task OnCompletedAsync(IEnumerable files) { progressPercent = myFileByBuffer!.ProgressPercent; progressTitle = myFileByBuffer!.ProgressTitle; foreach (var file in Files) { var extension = Path.GetExtension(file.Value); if (extension is ".xml") { await ImportXmlAndShowResultAsync(file.Value); } else if (extension is ".zip") { var unzippedFiles = UnzipAndListFiles(file.Value); foreach (var unzippedFile in unzippedFiles) { await ImportXmlAndShowResultAsync(unzippedFile); File.Delete(unzippedFile); } } File.Delete(file.Value); } Files.Clear(); await OnImported.InvokeAsync(); } private async Task ImportXmlAndShowResultAsync(string fileName) { var messages = await fileService.ImportAccountStatementFileAsync(fileName); foreach (var message in messages) { await ShowImportResultAsync(message); } } private IReadOnlyList UnzipAndListFiles(string zipFilePath) { var tempExtractPath = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(Path.GetRandomFileName())); Directory.CreateDirectory(tempExtractPath); ZipFile.ExtractToDirectory(zipFilePath, tempExtractPath); return new List(Directory.GetFiles(tempExtractPath, "*", SearchOption.AllDirectories)); } private async Task ShowImportResultAsync(MessageDataset message) { var joinedDetails = string.Join(", ", message.Lines); var text = $"{message.Title}: {joinedDetails}"; if (message.Status == MessageStatus.Success) { ShowToast(text, ToastIntent.Success); } else if (message.Status == MessageStatus.Info) { ShowToast(text, ToastIntent.Info); } else if (message.Status == MessageStatus.Warning) { await ShowMessageAsync(text, MessageIntent.Warning); } else if (message.Status == MessageStatus.Error) { await ShowMessageAsync(text, MessageIntent.Error); } } private async Task ShowMessageAsync(string message, MessageIntent intent) { await messageService.ShowMessageBarAsync(message, intent, "MESSAGES_TOP"); } private void ShowToast(string message, ToastIntent intent) { toastService.ShowToast(intent, message, 3000); } }