@using Microsoft.Extensions.Logging @using SteUp.Shared.Components.Layout @using SteUp.Shared.Components.Layout.Overlay @using SteUp.Shared.Components.Layout.Spinner @using SteUp.Shared.Components.SingleElements.Card.ModalForm @using SteUp.Shared.Components.SingleElements.MessageBox @using SteUp.Shared.Core.Dto @using SteUp.Shared.Core.Entities @using SteUp.Shared.Core.Enum @using SteUp.Shared.Core.Interface.IntegryApi @using SteUp.Shared.Core.Interface.LocalDb @using SteUp.Shared.Core.Interface.System @using SteUp.Shared.Core.Messages.Scanner @inject INetworkService NetworkService @inject IDialogService Dialog @inject IIntegryApiService IntegryApiService @inject IFileManager FileManager @inject IIspezioniService IspezioniService @inject IIntegrySteupService IntegrySteupService @inject OnScannerService OnScannerService @inject ILogger Logger
@foreach (var fasi in SteupDataService.Reparti) { @fasi.Descrizione } @foreach (var type in SteupDataService.TipiAttività.Where(x => x.CodJfas.EqualsIgnoreCase(Scheda.CodJfas!))) { @type.ActivityTypeId } @if (FileLoading) {
} else if (!AttachedList.IsNullOrEmpty()) {
@foreach (var item in AttachedList!.Select((p, index) => new { p, index })) { @if (!item.p.ThumbPath.IsNullOrEmpty()) { } @item.p.Name @if (item.p.ToUpload) { } }
} @if (!ReadOnly) {
Aggiungi foto
} @if (!ReadOnly) {
} @if (!Scheda.Articoli.IsNullOrEmpty()) {
@foreach (var articolo in Scheda.Articoli) { @articolo.Descrizione Barcode: @articolo.Barcode }
}
@if (NetworkService.ConnectionAvailable && !ReadOnly) {
Consulta articoli
}
Suggerisci note descrittive
@code { [CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!; [Parameter] public required string CodMdep { get; set; } [Parameter] public required DateTime Data { get; set; } [Parameter] public bool IsNew { get; set; } [Parameter] public bool ReadOnly { get; set; } [Parameter] public Scheda Scheda { get; set; } = new(); private string? ManualBarcode { get; set; } //Overlay private bool VisibleOverlay { get; set; } private bool SuccessAnimation { get; set; } private bool OnLoading { get; set; } private string? TextLoading { get; set; } private bool FileLoading { get; set; } private ConfirmUpdateActivity _confirmUpdateMessage = null!; private MudForm _form = null!; private string? LabelSave { get; set; } private bool IsDirty { get; set; } private Scheda _originalScheda = null!; private List? AttachedList { get; set; } protected override void OnInitialized() { Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter; OnScannerService.OnNewScanSuccessful += HandleNewScanSuccessful; OnScannerService.OnErrorScan += OnErrorScan; _originalScheda = Scheda.Clone(); Snackbar.Configuration.PositionClass = Defaults.Classes.Position.TopCenter; LoadAttached(); } private void LoadAttached() { if (Scheda.ImageNames == null) return; FileLoading = true; StateHasChanged(); Task.Run(async () => { var fileList = await FileManager.GetInspectionFiles( new Ispezione { CodMdep = CodMdep, Data = Data, Rilevatore = UserSession.User.Username }, Scheda.ImageNames ); await InvokeAsync(() => { AttachedList = fileList; FileLoading = false; StateHasChanged(); }); }); } private async Task Save() { VisibleOverlay = true; StateHasChanged(); SaveSchedaResponseDto? apiResponse = null; try { if (NetworkService.ConnectionAvailable) { apiResponse = await IntegrySteupService.SaveScheda( new SaveRequestDto { LocalIdScheda = Scheda.Id, ActivityTypeId = Scheda.ActivityTypeId, CodJfas = Scheda.CodJfas, CodMdep = CodMdep, DataCreazione = Data, Note = Scheda.Note, PersonaRif = Scheda.Responsabile, Barcodes = Scheda.Articoli.ConvertAll(x => x.Barcode), Scandeza = (ScadenzaEnum)Scheda.Scadenza, ParentActivityId = IsNew ? null : Scheda.Ispezione?.ActivityId } ); } } catch (Exception e) { var message = e.Message; Logger.LogError(e, message); Console.WriteLine(message); await Dialog.ShowError(message); } if (IsNew) await NewSave(apiResponse); else await Update(apiResponse); if (Scheda.ActivityId.IsValorized()) await UploadFile(Scheda); await FileManager.CleanTempStorageAsync(); SuccessAnimation = true; StateHasChanged(); await Task.Delay(1250); DisposeMessage(); MudDialog.Close(Scheda); } private async Task NewSave(SaveSchedaResponseDto? apiResponse) { if (!AttachedList.IsNullOrEmpty()) { foreach (var attached in AttachedList!) { var fileNameAdded = await FileManager.SaveInspectionFile( new Ispezione { CodMdep = CodMdep, Data = Data, Rilevatore = UserSession.User.Username }, attached.FileBytes!, attached.Name! ); Scheda.ImageNames ??= []; if (fileNameAdded != null) Scheda.ImageNames.Add(fileNameAdded); } } if (apiResponse != null) { await IspezioniService.UpdateActivityIdIspezioneAsync(CodMdep, Data, UserSession.User.Username, apiResponse.ActivityIdIspezione ); Scheda.ActivityId = apiResponse.ActivityIdScheda; } await IspezioniService.AddSchedaAsync(CodMdep, Data, UserSession.User.Username, Scheda); } private async Task Update(SaveSchedaResponseDto? apiResponse) { if (!AttachedList.IsNullOrEmpty()) { foreach (var attached in AttachedList!.Where(x => !x.SavedOnAppData)) { var ispezione = new Ispezione { CodMdep = CodMdep, Data = Data, Rilevatore = UserSession.User.Username }; if (!attached.ToRemove) { var fileNameAdded = await FileManager.SaveInspectionFile( ispezione, attached.FileBytes!, attached.Name! ); Scheda.ImageNames ??= []; if (fileNameAdded != null) Scheda.ImageNames.Add(fileNameAdded); } else _ = FileManager.RemoveInspectionFile(ispezione, attached.Name!); } } Scheda.ActivityId = apiResponse?.ActivityIdScheda; await IspezioniService.UpdateSchedaAsync(Scheda); if (apiResponse != null) await IspezioniService.UpdateActivityIdIspezioneAsync(CodMdep, Data, UserSession.User.Username, apiResponse.ActivityIdIspezione ); } private async Task UploadFile(Scheda scheda) { if (AttachedList.IsNullOrEmpty()) return; var ispezione = new Ispezione { CodMdep = CodMdep, Data = Data, Rilevatore = UserSession.User.Username }; foreach (var file in AttachedList!.Where(x => x.ToUpload)) { if (file.FileBytes == null || file.Name == null) continue; await IntegrySteupService.UploadFile(scheda.ActivityId!, file.FileBytes, file.Name); var newPath = await FileManager.MoveInspectionFileFromToUploadToFinal(ispezione, file.Name); if (newPath == null) continue; var filePathToRemove = FileManager.GetFileToUploadDir(ispezione, file.Name); scheda.ImageNames!.Remove(filePathToRemove); scheda.ImageNames.Add(newPath); } await IspezioniService.UpdateFileListSchedaAsync(scheda.Id, scheda.ImageNames); } private async Task Cancel() { if (await CheckSavePreAction()) { await FileManager.CleanTempStorageAsync(); DisposeMessage(); MudDialog.Cancel(); } } #region Form private void OnAfterChangeReparto() { Scheda.ActivityTypeId = null; OnAfterChangeValue(); } private void OnAfterChangeValue() { RecalcDirty(); StateHasChanged(); } private void RecalcDirty(bool forceTrue = false) { IsDirty = forceTrue || !ValueComparer.AreEqual(Scheda, _originalScheda); if (IsDirty) LabelSave = !IsNew ? "Aggiorna" : "Salva"; else LabelSave = null; } private static class ValueComparer { public static bool AreEqual(Scheda? a, Scheda? b) { if (a is null || b is null) return a == b; return a.CodJfas == b.CodJfas && a.DescrizioneReparto == b.DescrizioneReparto && a.ActivityTypeId == b.ActivityTypeId && a.Note == b.Note && a.Responsabile == b.Responsabile && a.Scadenza == b.Scadenza; } } private async Task CheckSavePreAction() { if (!IsDirty) return true; var resul = await _confirmUpdateMessage.ShowAsync(); if (resul is not true) return true; VisibleOverlay = true; StateHasChanged(); await Submit(); VisibleOverlay = false; StateHasChanged(); return false; } private async Task Submit() { await _form.Validate(); if (_form.IsValid) await Save(); } #endregion #region File private async Task OpenAddAttached() { var result = await Dialog.OpenAddAttached(); if (result is not { Canceled: false, Data: List attachedList }) return; OnLoading = true; await InvokeAsync(StateHasChanged); await Task.Yield(); // prepara placeholder in UI subito (così vedi le card con spinner) AttachedList ??= []; foreach (var a in attachedList) AttachedList.Add(new AttachedDto { Name = a.Name, MimeType = a.MimeType, FileBytes = a.FileBytes }); await InvokeAsync(StateHasChanged); RecalcDirty(true); // Processa in background e aggiorna UI man mano (o a blocchi) _ = Task.Run(async () => { for (var i = 0; i < attachedList.Count; i++) { var a = attachedList[i]; if (a.FileBytes is null || a.Name is null) continue; var (origUrl, thumbUrl) = await FileManager.SaveAndCreateThumbAsync(a.FileBytes, a.Name); await InvokeAsync(() => { var target = AttachedList![AttachedList.Count - attachedList.Count + i]; target.TempPath = origUrl; target.ThumbPath = thumbUrl; target.ToUpload = true; StateHasChanged(); }); } await InvokeAsync(() => { OnLoading = false; StateHasChanged(); }); }); } private void OpenSelectArt() { if (Scheda.CodJfas.IsNullOrEmpty()) { Snackbar.Clear(); Snackbar.Add("Selezionare prima il reparto", Severity.Error); return; } OnLoading = true; TextLoading = "Download articoli in griglia"; StateHasChanged(); _ = Task.Run(async () => { List? articoli; try { articoli = await IntegrySteupService.RetrieveGrigliaPlu( new RetrieveGrigliaPluRequestDto { CodMdep = CodMdep, ActivityTypeId = Scheda.ActivityTypeId, CodJfas = Scheda.CodJfas } ); } catch (Exception e) { Console.WriteLine(e.Message); await InvokeAsync(() => { OnLoading = false; TextLoading = null; StateHasChanged(); OnError(e, e.Message); }); return; } var modal = await Dialog.OpenSelectArt(articoli); await InvokeAsync(() => { OnLoading = false; TextLoading = null; StateHasChanged(); }); if (modal is { Canceled: false, Data: List articoliSelezionati }) { Scheda.Articoli.AddRange(articoliSelezionati.ConvertAll(x => new SchedaArticolo { Barcode = x.Barcode, Descrizione = x.Descrizione }) ); await InvokeAsync(StateHasChanged); } }); } private void OnRemoveAttached(int index) { if (AttachedList is null || index < 0 || index >= AttachedList.Count) return; if (AttachedList[index].SavedOnAppData) AttachedList[index].ToRemove = true; AttachedList.RemoveAt(index); RecalcDirty(true); StateHasChanged(); } #endregion private void SuggestActivityDescription() { if (Scheda.ActivityTypeId == null) { Snackbar.Add("Indicare prima il motivo", Severity.Error); return; } VisibleOverlay = true; StateHasChanged(); _ = Task.Run(async () => { var activityDescriptions = await IntegryApiService.SuggestActivityDescription(Scheda.ActivityTypeId); var modal = await Dialog.OpenSuggestActivityDescription(activityDescriptions); if (modal is { Canceled: false, Data: not null }) Scheda.Note = modal.Data!.ToString(); VisibleOverlay = false; await InvokeAsync(StateHasChanged); }); } #region Scanner private void OnManualBarcodeSet() { if (ManualBarcode == null) return; HandleNewScanSuccessful(ManualBarcode); ManualBarcode = null; } private async void HandleNewScanSuccessful(string? value) { try { if (value is null) return; if (Scheda.Articoli.Any(x => x.Barcode.Equals(value))) return; await InvokeAsync(() => { OnLoading = true; StateHasChanged(); }); var art = await IntegrySteupService.RetrieveArtFromBarcode(value); await InvokeAsync(() => { OnLoading = false; StateHasChanged(); if (art != null) { RecalcDirty(true); Scheda.Articoli.Add(new SchedaArticolo { Barcode = art.Barcode, Descrizione = art.Descrizione }); StateHasChanged(); } else { OnError(null, "Nessun articolo trovato"); } }); } catch (Exception e) { Console.WriteLine(e.Message); await InvokeAsync(() => { OnLoading = false; StateHasChanged(); }); OnError(e, e.Message); } } private void OnErrorScan(string? value) => OnError(new Exception(value), value); #endregion private void OnError(Exception? e, string? errorMessage) { if (e != null) Logger.LogError(e, errorMessage); if (errorMessage == null) return; _ = Dialog.ShowError(errorMessage); } private void RemoveArt(string barcode) { var index = Scheda.Articoli.FindIndex(x => x.Barcode.Equals(barcode)); if (index < 0) return; RecalcDirty(true); Scheda.Articoli.RemoveAt(index); StateHasChanged(); } private void DisposeMessage() { OnScannerService.OnNewScanSuccessful -= HandleNewScanSuccessful; OnScannerService.OnErrorScan -= OnErrorScan; } }