Compare commits
10 Commits
ab9578a45f
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
| 43f17c1410 | |||
| 0abe88939b | |||
| e57738a37f | |||
| 21ee5137b0 | |||
| 2d938fb210 | |||
| 3760e38c8d | |||
| e1e0c91db5 | |||
| 99a5395a1f | |||
| 8fbeaf8637 | |||
| 63368748ab |
@@ -1,4 +1,5 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using System.Linq.Expressions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using SteUp.Shared.Core.Entities;
|
using SteUp.Shared.Core.Entities;
|
||||||
using SteUp.Shared.Core.Enum;
|
using SteUp.Shared.Core.Enum;
|
||||||
using SteUp.Shared.Core.Helpers;
|
using SteUp.Shared.Core.Helpers;
|
||||||
@@ -17,8 +18,15 @@ public class IspezioniService(AppDbContext db) : IIspezioniService
|
|||||||
x.Data == data &&
|
x.Data == data &&
|
||||||
x.Rilevatore == rilevatore);
|
x.Rilevatore == rilevatore);
|
||||||
|
|
||||||
public Task<List<Ispezione>> GetAllIspezioniWithSchedeAsync() =>
|
public Task<List<Ispezione>> GetAllIspezioni(string rilevatore) =>
|
||||||
db.Ispezioni
|
db.Ispezioni
|
||||||
|
.Where(x => x.Rilevatore.Equals(rilevatore, StringComparison.InvariantCultureIgnoreCase))
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToListAsync();
|
||||||
|
|
||||||
|
public Task<List<Ispezione>> GetAllIspezioniWithSchedeAsync(string rilevatore) =>
|
||||||
|
db.Ispezioni
|
||||||
|
.Where(x => x.Rilevatore.Equals(rilevatore, StringComparison.InvariantCultureIgnoreCase))
|
||||||
.Include(x => x.Schede)
|
.Include(x => x.Schede)
|
||||||
.ThenInclude(s => s.Articoli)
|
.ThenInclude(s => s.Articoli)
|
||||||
.AsNoTracking()
|
.AsNoTracking()
|
||||||
@@ -67,15 +75,16 @@ public class IspezioniService(AppDbContext db) : IIspezioniService
|
|||||||
await db.SaveChangesAsync();
|
await db.SaveChangesAsync();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> UpdateStatoIspezioneAsync(string codMdep, DateTime data, string rilevatore, StatusEnum stato)
|
public async Task<bool> UpdateStatoIspezioneAsync(string codMdep, DateTime data, string rilevatore,
|
||||||
|
StatusEnum stato)
|
||||||
{
|
{
|
||||||
var ispezione = await db.Ispezioni
|
var ispezione = await db.Ispezioni
|
||||||
.FirstOrDefaultAsync(x =>
|
.FirstOrDefaultAsync(x =>
|
||||||
x.CodMdep == codMdep &&
|
x.CodMdep == codMdep &&
|
||||||
x.Data == data &&
|
x.Data == data &&
|
||||||
x.Rilevatore == rilevatore);
|
x.Rilevatore == rilevatore);
|
||||||
|
|
||||||
if (ispezione is null)
|
if (ispezione is null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -93,7 +102,7 @@ public class IspezioniService(AppDbContext db) : IIspezioniService
|
|||||||
x.CodMdep == codMdep &&
|
x.CodMdep == codMdep &&
|
||||||
x.Data == data &&
|
x.Data == data &&
|
||||||
x.Rilevatore == rilevatore);
|
x.Rilevatore == rilevatore);
|
||||||
|
|
||||||
if (ispezione is null)
|
if (ispezione is null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -175,6 +184,17 @@ public class IspezioniService(AppDbContext db) : IIspezioniService
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> UpdateFileListSchedaAsync(int schedaId, List<string>? imageNames)
|
||||||
|
{
|
||||||
|
var scheda = await db.Schede.FirstOrDefaultAsync(x => x.Id == schedaId);
|
||||||
|
if (scheda is null) return false;
|
||||||
|
|
||||||
|
scheda.ImageNames = imageNames;
|
||||||
|
db.Schede.Update(scheda);
|
||||||
|
await db.SaveChangesAsync();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<bool> DeleteSchedaAsync(int schedaId)
|
public async Task<bool> DeleteSchedaAsync(int schedaId)
|
||||||
{
|
{
|
||||||
var scheda = await db.Schede.FirstOrDefaultAsync(x => x.Id == schedaId);
|
var scheda = await db.Schede.FirstOrDefaultAsync(x => x.Id == schedaId);
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using SteUp.Maui.Core.UtilityException;
|
||||||
|
|
||||||
namespace SteUp.Maui
|
namespace SteUp.Maui
|
||||||
{
|
{
|
||||||
public partial class App
|
public partial class App
|
||||||
{
|
{
|
||||||
public App()
|
public App(ILogger<App> logger)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
GlobalExceptionHandler.Register(logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Window CreateWindow(IActivationState? activationState)
|
protected override Window CreateWindow(IActivationState? activationState)
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
using Microsoft.AspNetCore.Components.Authorization;
|
using Microsoft.AspNetCore.Components.Authorization;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using SteUp.Data.LocalDb;
|
using SteUp.Data.LocalDb;
|
||||||
using SteUp.Data.LocalDb.EntityServices;
|
using SteUp.Data.LocalDb.EntityServices;
|
||||||
|
using SteUp.Maui.Core.Logger;
|
||||||
using SteUp.Maui.Core.Services;
|
using SteUp.Maui.Core.Services;
|
||||||
using SteUp.Maui.Core.System;
|
using SteUp.Maui.Core.System;
|
||||||
using SteUp.Maui.Core.System.Network;
|
using SteUp.Maui.Core.System.Network;
|
||||||
@@ -45,6 +47,7 @@ public static class CoreModule
|
|||||||
{
|
{
|
||||||
builder.Services.AddSingleton<INetworkService, NetworkService>();
|
builder.Services.AddSingleton<INetworkService, NetworkService>();
|
||||||
builder.Services.AddSingleton<IAttachedService, AttachedService>();
|
builder.Services.AddSingleton<IAttachedService, AttachedService>();
|
||||||
|
builder.Services.AddSingleton<IFileManager, FileManager>();
|
||||||
builder.Services.AddSingleton<IBarcodeReaderService, HoneywellScannerService>();
|
builder.Services.AddSingleton<IBarcodeReaderService, HoneywellScannerService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,5 +78,17 @@ public static class CoreModule
|
|||||||
builder.Services.AddSingleton<IDbInitializer, DbInitializer>();
|
builder.Services.AddSingleton<IDbInitializer, DbInitializer>();
|
||||||
builder.Services.AddSingleton<IIspezioniService, IspezioniService>();
|
builder.Services.AddSingleton<IIspezioniService, IspezioniService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RegisterLoggerServices()
|
||||||
|
{
|
||||||
|
var logPath = Path.Combine(FileSystem.AppDataDirectory, "logs");
|
||||||
|
const string logFilePrefix = "SteUp-log";
|
||||||
|
|
||||||
|
builder.Services.AddLogging(loggingBuilder =>
|
||||||
|
{
|
||||||
|
loggingBuilder.AddProvider(new FileLoggerProvider(logPath, logFilePrefix));
|
||||||
|
loggingBuilder.SetMinimumLevel(LogLevel.Information);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
185
SteUp.Maui/Core/Logger/FileLogger.cs
Normal file
185
SteUp.Maui/Core/Logger/FileLogger.cs
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SteUp.Maui.Core.Logger;
|
||||||
|
|
||||||
|
public class FileLogger : ILogger
|
||||||
|
{
|
||||||
|
private readonly string _path;
|
||||||
|
private readonly string _fileNamePrefix;
|
||||||
|
private readonly string _categoryName;
|
||||||
|
private readonly Lock _lock = new();
|
||||||
|
private readonly int _retentionDays;
|
||||||
|
private string? _currentFileName;
|
||||||
|
private DateTime _currentFileDate;
|
||||||
|
private DateTime _lastCleanupDate;
|
||||||
|
|
||||||
|
public FileLogger(string path, string fileNamePrefix, string categoryName, int retentionDays = 60)
|
||||||
|
{
|
||||||
|
_path = path;
|
||||||
|
_fileNamePrefix = fileNamePrefix;
|
||||||
|
_retentionDays = retentionDays;
|
||||||
|
_lastCleanupDate = DateTime.MinValue;
|
||||||
|
_categoryName = categoryName;
|
||||||
|
|
||||||
|
if (!Directory.Exists(path))
|
||||||
|
Directory.CreateDirectory(path);
|
||||||
|
|
||||||
|
UpdateCurrentFileName();
|
||||||
|
TryCleanOldLogs();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Elimina i log più vecchi di <see cref="_retentionDays"/> giorni.
|
||||||
|
/// Viene eseguita al massimo una volta al giorno.
|
||||||
|
/// </summary>
|
||||||
|
private void ClearOldLogs()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var cutoff = DateTime.Now.Date.AddDays(-_retentionDays);
|
||||||
|
var logFiles = Directory.GetFiles(_path, $"{_fileNamePrefix}-*.log");
|
||||||
|
|
||||||
|
foreach (var file in logFiles)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var fileName = Path.GetFileNameWithoutExtension(file);
|
||||||
|
|
||||||
|
var datePart = fileName[(_fileNamePrefix.Length + 1)..];
|
||||||
|
|
||||||
|
if (!DateTime.TryParseExact(datePart, "yyyy-MM-dd",
|
||||||
|
CultureInfo.InvariantCulture,
|
||||||
|
DateTimeStyles.None,
|
||||||
|
out var fileDate) || fileDate >= cutoff) continue;
|
||||||
|
File.Delete(file);
|
||||||
|
Debug.WriteLine($"[FileLogger] Log eliminato: {file}");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"[FileLogger] Errore durante l'eliminazione del file {file}: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"[FileLogger] Errore durante la pulizia dei log: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Esegue la pulizia dei log solo se non è già stata eseguita oggi.
|
||||||
|
/// </summary>
|
||||||
|
private void TryCleanOldLogs()
|
||||||
|
{
|
||||||
|
var today = DateTime.Now.Date;
|
||||||
|
if (_lastCleanupDate == today) return;
|
||||||
|
_lastCleanupDate = today;
|
||||||
|
ClearOldLogs();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCurrentFileName()
|
||||||
|
{
|
||||||
|
var today = DateTime.Now.Date;
|
||||||
|
if (_currentFileName != null && _currentFileDate == today) return;
|
||||||
|
_currentFileDate = today;
|
||||||
|
_currentFileName = $"{_fileNamePrefix}-{today:yyyy-MM-dd}.log";
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDisposable? BeginScope<TState>(TState state) => null;
|
||||||
|
|
||||||
|
public bool IsEnabled(LogLevel logLevel) => logLevel != LogLevel.None;
|
||||||
|
|
||||||
|
public void Log<TState>(
|
||||||
|
LogLevel logLevel,
|
||||||
|
EventId eventId,
|
||||||
|
TState state,
|
||||||
|
Exception? exception,
|
||||||
|
Func<TState, Exception?, string> formatter)
|
||||||
|
{
|
||||||
|
if (!IsEnabled(logLevel))
|
||||||
|
return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
UpdateCurrentFileName();
|
||||||
|
TryCleanOldLogs();
|
||||||
|
|
||||||
|
if (_currentFileName == null) return;
|
||||||
|
|
||||||
|
var fullPath = Path.Combine(_path, _currentFileName);
|
||||||
|
var logEntry = BuildLogEntry(logLevel, eventId, state, exception, formatter);
|
||||||
|
|
||||||
|
File.AppendAllText(fullPath, logEntry + Environment.NewLine + Environment.NewLine);
|
||||||
|
Debug.WriteLine($"[FileLogger] {logEntry}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"[FileLogger] Errore durante la scrittura del log: {ex}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string BuildLogEntry<TState>(
|
||||||
|
LogLevel logLevel,
|
||||||
|
EventId eventId,
|
||||||
|
TState state,
|
||||||
|
Exception? exception,
|
||||||
|
Func<TState, Exception?, string> formatter)
|
||||||
|
{
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.Append($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}]");
|
||||||
|
sb.Append($" [{GetLogLevelShort(logLevel)}]");
|
||||||
|
sb.Append($" [{_categoryName}]");
|
||||||
|
|
||||||
|
if (eventId.Id != 0 || !string.IsNullOrEmpty(eventId.Name))
|
||||||
|
sb.Append($" [{eventId}]");
|
||||||
|
|
||||||
|
sb.Append($" {formatter(state, exception)}");
|
||||||
|
|
||||||
|
if (exception != null)
|
||||||
|
AppendException(sb, exception);
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AppendException(StringBuilder sb, Exception exception, int depth = 0)
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
var indent = depth == 0 ? "" : " Inner ";
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.Append($"{indent}Exception: {exception.GetType().FullName}: {exception.Message}");
|
||||||
|
if (!string.IsNullOrWhiteSpace(exception.StackTrace))
|
||||||
|
{
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.Append($"{indent}StackTrace: {exception.StackTrace.Trim()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exception.InnerException != null)
|
||||||
|
{
|
||||||
|
exception = exception.InnerException;
|
||||||
|
depth += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetLogLevelShort(LogLevel level) => level switch
|
||||||
|
{
|
||||||
|
LogLevel.Trace => "TRC",
|
||||||
|
LogLevel.Debug => "DBG",
|
||||||
|
LogLevel.Information => "INF",
|
||||||
|
LogLevel.Warning => "WRN",
|
||||||
|
LogLevel.Error => "ERR",
|
||||||
|
LogLevel.Critical => "CRT",
|
||||||
|
_ => "???"
|
||||||
|
};
|
||||||
|
}
|
||||||
14
SteUp.Maui/Core/Logger/FileLoggerProvider.cs
Normal file
14
SteUp.Maui/Core/Logger/FileLoggerProvider.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace SteUp.Maui.Core.Logger;
|
||||||
|
|
||||||
|
public class FileLoggerProvider(string path, string logFilePrefix, int retentionDays = 60)
|
||||||
|
: ILoggerProvider
|
||||||
|
{
|
||||||
|
public ILogger CreateLogger(string categoryName)
|
||||||
|
{
|
||||||
|
return new FileLogger(path, logFilePrefix, categoryName, retentionDays);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose() { }
|
||||||
|
}
|
||||||
@@ -1,15 +1,13 @@
|
|||||||
using SteUp.Shared.Core.Dto;
|
using Microsoft.Extensions.Logging;
|
||||||
using SteUp.Shared.Core.Entities;
|
using SteUp.Maui.Core.Utility;
|
||||||
|
using SteUp.Shared.Core.Dto;
|
||||||
using SteUp.Shared.Core.Helpers;
|
using SteUp.Shared.Core.Helpers;
|
||||||
using SteUp.Shared.Core.Interface.System;
|
using SteUp.Shared.Core.Interface.System;
|
||||||
|
|
||||||
namespace SteUp.Maui.Core.Services;
|
namespace SteUp.Maui.Core.Services;
|
||||||
|
|
||||||
public class AttachedService : IAttachedService
|
public class AttachedService(ILogger<FileManager> logger) : IAttachedService
|
||||||
{
|
{
|
||||||
private static string AttachedRoot =>
|
|
||||||
Path.Combine(FileSystem.CacheDirectory, "attached");
|
|
||||||
|
|
||||||
public async Task<AttachedDto?> SelectImageFromCamera()
|
public async Task<AttachedDto?> SelectImageFromCamera()
|
||||||
{
|
{
|
||||||
var cameraPerm = await Permissions.RequestAsync<Permissions.Camera>();
|
var cameraPerm = await Permissions.RequestAsync<Permissions.Camera>();
|
||||||
@@ -27,12 +25,13 @@ public class AttachedService : IAttachedService
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
logger.LogError(ex, ex.Message);
|
||||||
Console.WriteLine($"Errore cattura foto: {ex.Message}");
|
Console.WriteLine($"Errore cattura foto: {ex.Message}");
|
||||||
SentrySdk.CaptureException(ex);
|
SentrySdk.CaptureException(ex);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result is null ? null : await ConvertToDto(result, AttachedDto.TypeAttached.Image);
|
return result is null ? null : await UtilityFile.ConvertToDto(result, AttachedDto.TypeAttached.Image);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<AttachedDto>?> SelectImageFromGallery()
|
public async Task<List<AttachedDto>?> SelectImageFromGallery()
|
||||||
@@ -48,6 +47,7 @@ public class AttachedService : IAttachedService
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
logger.LogError(ex, ex.Message);
|
||||||
Console.WriteLine($"Errore selezione galleria: {ex.Message}");
|
Console.WriteLine($"Errore selezione galleria: {ex.Message}");
|
||||||
SentrySdk.CaptureException(ex);
|
SentrySdk.CaptureException(ex);
|
||||||
return null;
|
return null;
|
||||||
@@ -58,308 +58,9 @@ public class AttachedService : IAttachedService
|
|||||||
List<AttachedDto> returnList = [];
|
List<AttachedDto> returnList = [];
|
||||||
foreach (var fileResult in resultList)
|
foreach (var fileResult in resultList)
|
||||||
{
|
{
|
||||||
returnList.Add(await ConvertToDto(fileResult, AttachedDto.TypeAttached.Image));
|
returnList.Add(await UtilityFile.ConvertToDto(fileResult, AttachedDto.TypeAttached.Image));
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnList;
|
return returnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<AttachedDto> ConvertToDto(FileResult file, AttachedDto.TypeAttached type)
|
|
||||||
{
|
|
||||||
var stream = await file.OpenReadAsync();
|
|
||||||
using var ms = new MemoryStream();
|
|
||||||
await stream.CopyToAsync(ms);
|
|
||||||
|
|
||||||
return new AttachedDto
|
|
||||||
{
|
|
||||||
Name = file.FileName,
|
|
||||||
Path = file.FullPath,
|
|
||||||
MimeType = file.ContentType,
|
|
||||||
DimensionBytes = ms.Length,
|
|
||||||
FileBytes = ms.ToArray(),
|
|
||||||
Type = type
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<AttachedDto> ConvertToDto(FileInfo file, AttachedDto.TypeAttached type, bool isFromToUpload)
|
|
||||||
{
|
|
||||||
var (origUrl, thumbUrl) = await SaveAndCreateThumbAsync(
|
|
||||||
await File.ReadAllBytesAsync(file.FullName),
|
|
||||||
file.Name
|
|
||||||
);
|
|
||||||
|
|
||||||
return new AttachedDto
|
|
||||||
{
|
|
||||||
Name = file.Name,
|
|
||||||
Path = file.FullName,
|
|
||||||
TempPath = origUrl,
|
|
||||||
ThumbPath = thumbUrl,
|
|
||||||
Type = type,
|
|
||||||
SavedOnAppData = true,
|
|
||||||
ToUpload = isFromToUpload
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private const string ToUploadFolderName = "toUpload";
|
|
||||||
|
|
||||||
private string GetInspectionBaseDir(Ispezione ispezione)
|
|
||||||
{
|
|
||||||
var baseDir = FileSystem.AppDataDirectory;
|
|
||||||
return Path.Combine(baseDir, $"attached_{GetInspectionKey(ispezione)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetInspectionToUploadDir(Ispezione ispezione)
|
|
||||||
=> Path.Combine(GetInspectionBaseDir(ispezione), ToUploadFolderName);
|
|
||||||
|
|
||||||
private string GetInspectionFinalDir(Ispezione ispezione)
|
|
||||||
=> GetInspectionBaseDir(ispezione);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Ritorna i file dell'ispezione filtrati per nome.
|
|
||||||
/// Per default include sia "final" sia "toUpload" (utile per UI).
|
|
||||||
/// </summary>
|
|
||||||
public async Task<List<AttachedDto>?> GetInspectionFiles(
|
|
||||||
Ispezione ispezione,
|
|
||||||
List<string> fileNameFilter,
|
|
||||||
bool includeToUpload,
|
|
||||||
CancellationToken ct)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(ispezione);
|
|
||||||
ArgumentNullException.ThrowIfNull(fileNameFilter);
|
|
||||||
|
|
||||||
var baseDir = GetInspectionBaseDir(ispezione);
|
|
||||||
if (!Directory.Exists(baseDir)) return null;
|
|
||||||
|
|
||||||
var result = new List<AttachedDto>();
|
|
||||||
|
|
||||||
var finalDir = GetInspectionFinalDir(ispezione);
|
|
||||||
if (Directory.Exists(finalDir))
|
|
||||||
{
|
|
||||||
var finalFiles = new DirectoryInfo(finalDir)
|
|
||||||
.GetFiles("*", SearchOption.TopDirectoryOnly);
|
|
||||||
|
|
||||||
foreach (var file in finalFiles)
|
|
||||||
{
|
|
||||||
if (file.Directory?.Name == ToUploadFolderName)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!fileNameFilter.Contains(file.Name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ct.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
result.Add(await ConvertToDto(
|
|
||||||
file,
|
|
||||||
AttachedDto.TypeAttached.Image,
|
|
||||||
isFromToUpload: false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!includeToUpload) return result;
|
|
||||||
|
|
||||||
var toUploadDir = GetInspectionToUploadDir(ispezione);
|
|
||||||
if (!Directory.Exists(toUploadDir)) return result;
|
|
||||||
|
|
||||||
var toUploadFiles = new DirectoryInfo(toUploadDir)
|
|
||||||
.GetFiles("*", SearchOption.TopDirectoryOnly);
|
|
||||||
|
|
||||||
foreach (var file in toUploadFiles)
|
|
||||||
{
|
|
||||||
if (!fileNameFilter.Contains(file.Name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ct.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
result.Add(await ConvertToDto(
|
|
||||||
file,
|
|
||||||
AttachedDto.TypeAttached.Image,
|
|
||||||
isFromToUpload: true));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Salva SEMPRE in /toUpload.
|
|
||||||
/// </summary>
|
|
||||||
public async Task<string?> SaveInspectionFile(
|
|
||||||
Ispezione ispezione,
|
|
||||||
byte[] file,
|
|
||||||
string fileName,
|
|
||||||
CancellationToken ct)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(ispezione);
|
|
||||||
ArgumentNullException.ThrowIfNull(file);
|
|
||||||
ArgumentException.ThrowIfNullOrWhiteSpace(fileName);
|
|
||||||
|
|
||||||
var toUploadDir = GetInspectionToUploadDir(ispezione);
|
|
||||||
Directory.CreateDirectory(toUploadDir);
|
|
||||||
|
|
||||||
var filePath = Path.Combine(toUploadDir, fileName);
|
|
||||||
await File.WriteAllBytesAsync(filePath, file, ct);
|
|
||||||
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<bool> MoveInspectionFileFromToUploadToFinal(
|
|
||||||
Ispezione ispezione,
|
|
||||||
string fileName,
|
|
||||||
bool overwrite,
|
|
||||||
CancellationToken ct)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(ispezione);
|
|
||||||
ArgumentException.ThrowIfNullOrWhiteSpace(fileName);
|
|
||||||
|
|
||||||
ct.ThrowIfCancellationRequested();
|
|
||||||
|
|
||||||
var toUploadDir = GetInspectionToUploadDir(ispezione);
|
|
||||||
var finalDir = GetInspectionFinalDir(ispezione);
|
|
||||||
|
|
||||||
if (!Directory.Exists(toUploadDir)) return Task.FromResult(false);
|
|
||||||
|
|
||||||
var sourcePath = Path.Combine(toUploadDir, fileName);
|
|
||||||
if (!File.Exists(sourcePath)) return Task.FromResult(false);
|
|
||||||
|
|
||||||
Directory.CreateDirectory(finalDir);
|
|
||||||
|
|
||||||
var destPath = Path.Combine(finalDir, fileName);
|
|
||||||
|
|
||||||
if (File.Exists(destPath))
|
|
||||||
{
|
|
||||||
if (!overwrite) return Task.FromResult(false);
|
|
||||||
File.Delete(destPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
File.Move(sourcePath, destPath);
|
|
||||||
|
|
||||||
// Pulizia: se /toUpload resta vuota la elimino
|
|
||||||
CleanupDirectoriesIfEmpty(ispezione);
|
|
||||||
|
|
||||||
return Task.FromResult(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rimuove un file cercandolo prima in /toUpload e poi in final (o viceversa).
|
|
||||||
/// Default: prova a cancellare ovunque.
|
|
||||||
/// </summary>
|
|
||||||
public bool RemoveInspectionFile(
|
|
||||||
Ispezione ispezione,
|
|
||||||
string fileName,
|
|
||||||
bool removeAlsoFromFinal,
|
|
||||||
bool removeAlsoFromToUpload)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(ispezione);
|
|
||||||
if (string.IsNullOrWhiteSpace(fileName)) return false;
|
|
||||||
|
|
||||||
var removed = false;
|
|
||||||
|
|
||||||
if (removeAlsoFromToUpload)
|
|
||||||
{
|
|
||||||
var toUploadPath = Path.Combine(GetInspectionToUploadDir(ispezione), fileName);
|
|
||||||
if (File.Exists(toUploadPath))
|
|
||||||
{
|
|
||||||
File.Delete(toUploadPath);
|
|
||||||
removed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removeAlsoFromFinal)
|
|
||||||
{
|
|
||||||
var finalPath = Path.Combine(GetInspectionFinalDir(ispezione), fileName);
|
|
||||||
if (File.Exists(finalPath))
|
|
||||||
{
|
|
||||||
File.Delete(finalPath);
|
|
||||||
removed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (removed)
|
|
||||||
CleanupDirectoriesIfEmpty(ispezione);
|
|
||||||
|
|
||||||
return removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CleanupDirectoriesIfEmpty(Ispezione ispezione)
|
|
||||||
{
|
|
||||||
var baseDir = GetInspectionBaseDir(ispezione);
|
|
||||||
var toUploadDir = GetInspectionToUploadDir(ispezione);
|
|
||||||
|
|
||||||
// 1) se /toUpload esiste e vuota => delete
|
|
||||||
if (Directory.Exists(toUploadDir) && !Directory.EnumerateFileSystemEntries(toUploadDir).Any())
|
|
||||||
Directory.Delete(toUploadDir);
|
|
||||||
|
|
||||||
// 2) se base dir vuota (attenzione: dopo delete toUpload) => delete
|
|
||||||
if (Directory.Exists(baseDir) && !Directory.EnumerateFileSystemEntries(baseDir).Any())
|
|
||||||
Directory.Delete(baseDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string> SaveToTempStorage(Stream file, string fileName, CancellationToken ct = default)
|
|
||||||
{
|
|
||||||
ArgumentNullException.ThrowIfNull(file);
|
|
||||||
|
|
||||||
if (file.CanSeek)
|
|
||||||
file.Position = 0;
|
|
||||||
|
|
||||||
fileName = Path.GetFileName(fileName);
|
|
||||||
|
|
||||||
var dir = FileSystem.CacheDirectory;
|
|
||||||
var filePath = Path.Combine(dir, fileName);
|
|
||||||
|
|
||||||
await using var fileStream = File.Create(filePath);
|
|
||||||
await file.CopyToAsync(fileStream, ct);
|
|
||||||
|
|
||||||
return filePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task CleanTempStorageAsync(CancellationToken ct = default)
|
|
||||||
{
|
|
||||||
return Task.Run(() =>
|
|
||||||
{
|
|
||||||
if (Directory.Exists(AttachedRoot))
|
|
||||||
Directory.Delete(AttachedRoot, true);
|
|
||||||
}, ct);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task OpenFile(string fileName, string filePath)
|
|
||||||
{
|
|
||||||
#if IOS
|
|
||||||
throw new NotImplementedException();
|
|
||||||
#else
|
|
||||||
return Launcher.OpenAsync(new OpenFileRequest
|
|
||||||
{
|
|
||||||
Title = "Apri file",
|
|
||||||
File = new ReadOnlyFile(filePath)
|
|
||||||
});
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<(string originalUrl, string thumbUrl)> SaveAndCreateThumbAsync(
|
|
||||||
byte[] bytes, string fileName, CancellationToken ct = default)
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(AttachedRoot);
|
|
||||||
|
|
||||||
var id = Guid.NewGuid().ToString("N");
|
|
||||||
var safeName = SanitizeFileName(fileName);
|
|
||||||
|
|
||||||
var originalFile = $"{id}_{safeName}";
|
|
||||||
var thumbFile = $"{id}_thumb.jpg";
|
|
||||||
|
|
||||||
var originalPath = Path.Combine(AttachedRoot, originalFile);
|
|
||||||
await File.WriteAllBytesAsync(originalPath, bytes, ct);
|
|
||||||
|
|
||||||
var thumbPath = Path.Combine(AttachedRoot, thumbFile);
|
|
||||||
await ImageThumb.CreateThumbnailAsync(originalPath, thumbPath, maxSide: 320, quality: 70, ct);
|
|
||||||
|
|
||||||
return ($"https://localfiles/attached/{originalFile}",
|
|
||||||
$"https://localfiles/attached/{thumbFile}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string SanitizeFileName(string fileName)
|
|
||||||
{
|
|
||||||
var name = Path.GetFileName(fileName);
|
|
||||||
return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, '_'));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetInspectionKey(Ispezione ispezione) =>
|
|
||||||
$"{ispezione.CodMdep}_{ispezione.Data:ddMMyyyy}_{ispezione.Rilevatore.ToLower()}";
|
|
||||||
}
|
}
|
||||||
488
SteUp.Maui/Core/Services/FileManager.cs
Normal file
488
SteUp.Maui/Core/Services/FileManager.cs
Normal file
@@ -0,0 +1,488 @@
|
|||||||
|
using System.IO.Compression;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using SteUp.Data.LocalDb;
|
||||||
|
using SteUp.Shared.Core.Dto;
|
||||||
|
using SteUp.Shared.Core.Entities;
|
||||||
|
using SteUp.Shared.Core.Helpers;
|
||||||
|
using SteUp.Shared.Core.Interface.System;
|
||||||
|
|
||||||
|
namespace SteUp.Maui.Core.Services;
|
||||||
|
|
||||||
|
public class FileManager(
|
||||||
|
IDbPathProvider dbPathProvider,
|
||||||
|
ILogger<FileManager> logger) : IFileManager
|
||||||
|
{
|
||||||
|
private static string AttachedRoot =>
|
||||||
|
Path.Combine(FileSystem.CacheDirectory, "attached");
|
||||||
|
|
||||||
|
private async Task<AttachedDto> ConvertToDto(FileInfo file, AttachedDto.TypeAttached type, bool isFromToUpload)
|
||||||
|
{
|
||||||
|
var (origUrl, thumbUrl) = await SaveAndCreateThumbAsync(
|
||||||
|
await File.ReadAllBytesAsync(file.FullName),
|
||||||
|
file.Name
|
||||||
|
);
|
||||||
|
|
||||||
|
return new AttachedDto
|
||||||
|
{
|
||||||
|
Name = file.Name,
|
||||||
|
Path = file.FullName,
|
||||||
|
TempPath = origUrl,
|
||||||
|
ThumbPath = thumbUrl,
|
||||||
|
Type = type,
|
||||||
|
SavedOnAppData = true,
|
||||||
|
ToUpload = isFromToUpload
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private const string ToUploadFolderName = "toUpload";
|
||||||
|
|
||||||
|
private string GetInspectionBaseDir(Ispezione ispezione)
|
||||||
|
{
|
||||||
|
var baseDir = FileSystem.AppDataDirectory;
|
||||||
|
return Path.Combine(baseDir, "attached", $"inspection_{GetInspectionKey(ispezione)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetInspectionToUploadDir(Ispezione ispezione)
|
||||||
|
=> Path.Combine(GetInspectionBaseDir(ispezione), ToUploadFolderName);
|
||||||
|
|
||||||
|
public string GetFileToUploadDir(Ispezione ispezione, string fileName) =>
|
||||||
|
Path.Combine(GetInspectionToUploadDir(ispezione), fileName);
|
||||||
|
|
||||||
|
private string GetInspectionFinalDir(Ispezione ispezione)
|
||||||
|
=> GetInspectionBaseDir(ispezione);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ritorna i file dell'ispezione filtrati per nome.
|
||||||
|
/// Per default include sia "final" sia "toUpload" (utile per UI).
|
||||||
|
/// </summary>
|
||||||
|
public async Task<List<AttachedDto>?> GetInspectionFiles(
|
||||||
|
Ispezione ispezione,
|
||||||
|
List<string> fileNameFilter,
|
||||||
|
bool includeToUpload,
|
||||||
|
CancellationToken ct)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(ispezione);
|
||||||
|
ArgumentNullException.ThrowIfNull(fileNameFilter);
|
||||||
|
|
||||||
|
var baseDir = GetInspectionBaseDir(ispezione);
|
||||||
|
if (!Directory.Exists(baseDir)) return null;
|
||||||
|
|
||||||
|
var result = new List<AttachedDto>();
|
||||||
|
|
||||||
|
var finalDir = GetInspectionFinalDir(ispezione);
|
||||||
|
if (Directory.Exists(finalDir))
|
||||||
|
{
|
||||||
|
var finalFiles = new DirectoryInfo(finalDir)
|
||||||
|
.GetFiles("*", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
|
foreach (var file in finalFiles)
|
||||||
|
{
|
||||||
|
if (file.Directory?.Name == ToUploadFolderName)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!fileNameFilter.Contains(file.FullName))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ct.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
result.Add(await ConvertToDto(
|
||||||
|
file,
|
||||||
|
AttachedDto.TypeAttached.Image,
|
||||||
|
isFromToUpload: false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!includeToUpload) return result;
|
||||||
|
|
||||||
|
var toUploadDir = GetInspectionToUploadDir(ispezione);
|
||||||
|
if (!Directory.Exists(toUploadDir)) return result;
|
||||||
|
|
||||||
|
var toUploadFiles = new DirectoryInfo(toUploadDir)
|
||||||
|
.GetFiles("*", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
|
foreach (var file in toUploadFiles)
|
||||||
|
{
|
||||||
|
if (!fileNameFilter.Contains(file.Name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ct.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
result.Add(await ConvertToDto(
|
||||||
|
file,
|
||||||
|
AttachedDto.TypeAttached.Image,
|
||||||
|
isFromToUpload: true));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Salva SEMPRE in /toUpload.
|
||||||
|
/// </summary>
|
||||||
|
public async Task<string?> SaveInspectionFile(
|
||||||
|
Ispezione ispezione,
|
||||||
|
byte[] file,
|
||||||
|
string fileName,
|
||||||
|
CancellationToken ct)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(ispezione);
|
||||||
|
ArgumentNullException.ThrowIfNull(file);
|
||||||
|
ArgumentException.ThrowIfNullOrWhiteSpace(fileName);
|
||||||
|
|
||||||
|
var toUploadDir = GetInspectionToUploadDir(ispezione);
|
||||||
|
Directory.CreateDirectory(toUploadDir);
|
||||||
|
|
||||||
|
var filePath = Path.Combine(toUploadDir, fileName);
|
||||||
|
await File.WriteAllBytesAsync(filePath, file, ct);
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<string?> MoveInspectionFileFromToUploadToFinal(
|
||||||
|
Ispezione ispezione,
|
||||||
|
string fileName,
|
||||||
|
bool overwrite,
|
||||||
|
CancellationToken ct)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(ispezione);
|
||||||
|
ArgumentException.ThrowIfNullOrWhiteSpace(fileName);
|
||||||
|
|
||||||
|
ct.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var toUploadDir = GetInspectionToUploadDir(ispezione);
|
||||||
|
var finalDir = GetInspectionFinalDir(ispezione);
|
||||||
|
|
||||||
|
if (!Directory.Exists(toUploadDir)) return Task.FromResult<string?>(null);
|
||||||
|
|
||||||
|
var sourcePath = Path.Combine(toUploadDir, fileName);
|
||||||
|
if (!File.Exists(sourcePath)) return Task.FromResult<string?>(null);
|
||||||
|
|
||||||
|
Directory.CreateDirectory(finalDir);
|
||||||
|
|
||||||
|
var destPath = Path.Combine(finalDir, fileName);
|
||||||
|
|
||||||
|
if (File.Exists(destPath))
|
||||||
|
{
|
||||||
|
if (!overwrite) return Task.FromResult<string?>(null);
|
||||||
|
File.Delete(destPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Move(sourcePath, destPath);
|
||||||
|
|
||||||
|
// Pulizia: se /toUpload resta vuota la elimino
|
||||||
|
CleanupDirectoriesIfEmpty(ispezione);
|
||||||
|
|
||||||
|
return Task.FromResult<string?>(destPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Rimuove un file cercandolo prima in /toUpload e poi in final (o viceversa).
|
||||||
|
/// Default: prova a cancellare ovunque.
|
||||||
|
/// </summary>
|
||||||
|
public bool RemoveInspectionFile(
|
||||||
|
Ispezione ispezione,
|
||||||
|
string fileName,
|
||||||
|
bool removeAlsoFromFinal,
|
||||||
|
bool removeAlsoFromToUpload)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(ispezione);
|
||||||
|
if (string.IsNullOrWhiteSpace(fileName)) return false;
|
||||||
|
|
||||||
|
var removed = false;
|
||||||
|
|
||||||
|
if (removeAlsoFromToUpload)
|
||||||
|
{
|
||||||
|
var toUploadPath = Path.Combine(GetInspectionToUploadDir(ispezione), fileName);
|
||||||
|
if (File.Exists(toUploadPath))
|
||||||
|
{
|
||||||
|
File.Delete(toUploadPath);
|
||||||
|
removed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removeAlsoFromFinal)
|
||||||
|
{
|
||||||
|
var finalPath = Path.Combine(GetInspectionFinalDir(ispezione), fileName);
|
||||||
|
if (File.Exists(finalPath))
|
||||||
|
{
|
||||||
|
File.Delete(finalPath);
|
||||||
|
removed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removed)
|
||||||
|
CleanupDirectoriesIfEmpty(ispezione);
|
||||||
|
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RemoveInspection(Ispezione ispezione, bool removeAlsoFromFinal, bool removeAlsoFromToUpload)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(ispezione);
|
||||||
|
|
||||||
|
var removedAnything = false;
|
||||||
|
|
||||||
|
if (removeAlsoFromToUpload)
|
||||||
|
TryDeleteDirectory(GetInspectionToUploadDir(ispezione));
|
||||||
|
|
||||||
|
if (removeAlsoFromFinal)
|
||||||
|
TryDeleteDirectory(GetInspectionFinalDir(ispezione));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
CleanupDirectoriesIfEmpty(ispezione);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
logger.LogError(e, e.Message);
|
||||||
|
SentrySdk.CaptureException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return removedAnything;
|
||||||
|
|
||||||
|
void TryDeleteDirectory(string? dir)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(dir)) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!Directory.Exists(dir)) return;
|
||||||
|
|
||||||
|
Directory.Delete(dir, recursive: true);
|
||||||
|
removedAnything = true;
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
logger.LogError(e, e.Message);
|
||||||
|
SentrySdk.CaptureException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CleanupDirectoriesIfEmpty(Ispezione ispezione)
|
||||||
|
{
|
||||||
|
var baseDir = GetInspectionBaseDir(ispezione);
|
||||||
|
var toUploadDir = GetInspectionToUploadDir(ispezione);
|
||||||
|
|
||||||
|
// 1) se /toUpload esiste e vuota => delete
|
||||||
|
if (Directory.Exists(toUploadDir) && !Directory.EnumerateFileSystemEntries(toUploadDir).Any())
|
||||||
|
Directory.Delete(toUploadDir);
|
||||||
|
|
||||||
|
// 2) se base dir vuota (attenzione: dopo delete toUpload) => delete
|
||||||
|
if (Directory.Exists(baseDir) && !Directory.EnumerateFileSystemEntries(baseDir).Any())
|
||||||
|
Directory.Delete(baseDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> SaveToTempStorage(Stream file, string fileName, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(file);
|
||||||
|
|
||||||
|
if (file.CanSeek)
|
||||||
|
file.Position = 0;
|
||||||
|
|
||||||
|
fileName = Path.GetFileName(fileName);
|
||||||
|
|
||||||
|
var dir = FileSystem.CacheDirectory;
|
||||||
|
var filePath = Path.Combine(dir, fileName);
|
||||||
|
|
||||||
|
await using var fileStream = File.Create(filePath);
|
||||||
|
await file.CopyToAsync(fileStream, ct);
|
||||||
|
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task CleanTempStorageAsync(CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
return Task.Run(() =>
|
||||||
|
{
|
||||||
|
if (Directory.Exists(AttachedRoot))
|
||||||
|
Directory.Delete(AttachedRoot, true);
|
||||||
|
}, ct);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task OpenFile(string fileName, string filePath)
|
||||||
|
{
|
||||||
|
#if IOS
|
||||||
|
throw new NotImplementedException();
|
||||||
|
#else
|
||||||
|
return Launcher.OpenAsync(new OpenFileRequest
|
||||||
|
{
|
||||||
|
Title = "Apri file",
|
||||||
|
File = new ReadOnlyFile(filePath)
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<(string originalUrl, string thumbUrl)> SaveAndCreateThumbAsync(
|
||||||
|
byte[] bytes, string fileName, CancellationToken ct = default)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(AttachedRoot);
|
||||||
|
|
||||||
|
var id = Guid.NewGuid().ToString("N");
|
||||||
|
var safeName = SanitizeFileName(fileName);
|
||||||
|
|
||||||
|
var originalFile = $"{id}_{safeName}";
|
||||||
|
var thumbFile = $"{id}_thumb.jpg";
|
||||||
|
|
||||||
|
var originalPath = Path.Combine(AttachedRoot, originalFile);
|
||||||
|
await File.WriteAllBytesAsync(originalPath, bytes, ct);
|
||||||
|
|
||||||
|
var thumbPath = Path.Combine(AttachedRoot, thumbFile);
|
||||||
|
await ImageThumb.CreateThumbnailAsync(originalPath, thumbPath, maxSide: 320, quality: 70, ct);
|
||||||
|
|
||||||
|
return ($"https://localfiles/attached/{originalFile}",
|
||||||
|
$"https://localfiles/attached/{thumbFile}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string SanitizeFileName(string fileName)
|
||||||
|
{
|
||||||
|
var name = Path.GetFileName(fileName);
|
||||||
|
return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, '_'));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetInspectionKey(Ispezione ispezione) =>
|
||||||
|
$"{ispezione.CodMdep}_{ispezione.Data:ddMMyyyy}_{ispezione.Rilevatore.ToLower()}";
|
||||||
|
|
||||||
|
public List<SendEmailDto.AttachmentsDto> GetFileForExport()
|
||||||
|
{
|
||||||
|
var attachments = new List<SendEmailDto.AttachmentsDto>();
|
||||||
|
|
||||||
|
// 1) log file singolo (se ti serve ancora)
|
||||||
|
var logFile = RetrieveLogFile();
|
||||||
|
if (!logFile.IsNullOrEmpty())
|
||||||
|
{
|
||||||
|
attachments.Add(new SendEmailDto.AttachmentsDto
|
||||||
|
{
|
||||||
|
FileName = $"logs_{DateTime.Today:yyyyMMdd}.zip",
|
||||||
|
FileContent = CreateZipBytes(logFile!)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) database zip
|
||||||
|
var dbZip = CreateDatabaseZipAttachment();
|
||||||
|
if (dbZip != null) attachments.Add(dbZip);
|
||||||
|
|
||||||
|
// 3) Img zip
|
||||||
|
var attachedInfo = new DirectoryInfo(Path.Combine(FileSystem.AppDataDirectory, "attached"));
|
||||||
|
if (!attachedInfo.Exists) return attachments;
|
||||||
|
|
||||||
|
var attachedFiles = attachedInfo
|
||||||
|
.EnumerateFiles("*", SearchOption.AllDirectories)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
if (attachedFiles.Count > 0)
|
||||||
|
{
|
||||||
|
attachments.Add(new SendEmailDto.AttachmentsDto
|
||||||
|
{
|
||||||
|
FileName = $"immagini_allegate_{DateTime.Today:yyyyMMdd}.zip",
|
||||||
|
FileContent = CreateZipBytes(attachedInfo.FullName, attachedFiles)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return attachments;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<FileInfo>? RetrieveLogFile()
|
||||||
|
{
|
||||||
|
var appDataPath = FileSystem.AppDataDirectory;
|
||||||
|
var targetDirectory = Path.Combine(appDataPath, "logs");
|
||||||
|
|
||||||
|
var directory = new DirectoryInfo(targetDirectory);
|
||||||
|
|
||||||
|
List<FileInfo>? files = null;
|
||||||
|
|
||||||
|
if (directory.Exists)
|
||||||
|
files = directory.GetFiles().ToList();
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SendEmailDto.AttachmentsDto? CreateDatabaseZipAttachment()
|
||||||
|
{
|
||||||
|
var files = new[]
|
||||||
|
{
|
||||||
|
new FileInfo(dbPathProvider.GetDbPath())
|
||||||
|
};
|
||||||
|
|
||||||
|
// Filtra solo quelli esistenti
|
||||||
|
var existingFiles = files.Where(f => f.Exists).ToList();
|
||||||
|
|
||||||
|
if (existingFiles.Count == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
using var memoryStream = new MemoryStream();
|
||||||
|
|
||||||
|
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
|
||||||
|
{
|
||||||
|
foreach (var file in existingFiles)
|
||||||
|
{
|
||||||
|
var entry = archive.CreateEntry(file.Name, CompressionLevel.Optimal);
|
||||||
|
|
||||||
|
using var entryStream = entry.Open();
|
||||||
|
using var fileStream = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||||
|
|
||||||
|
fileStream.CopyTo(entryStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SendEmailDto.AttachmentsDto
|
||||||
|
{
|
||||||
|
FileName = $"database_{DateTime.Now:yyyyMMdd_HHmm}.zip",
|
||||||
|
FileContent = memoryStream.ToArray()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] CreateZipBytes(IEnumerable<FileInfo> files)
|
||||||
|
{
|
||||||
|
using var ms = new MemoryStream();
|
||||||
|
using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, leaveOpen: true))
|
||||||
|
{
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
if (!file.Exists)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Nome dentro lo zip (evita path e collisioni minime)
|
||||||
|
var entryName = file.Name;
|
||||||
|
|
||||||
|
var entry = archive.CreateEntry(entryName, CompressionLevel.Optimal);
|
||||||
|
|
||||||
|
using var entryStream = entry.Open();
|
||||||
|
using var fileStream = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||||
|
|
||||||
|
fileStream.CopyTo(entryStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] CreateZipBytes(string rootDir, IEnumerable<FileInfo> files)
|
||||||
|
{
|
||||||
|
using var ms = new MemoryStream();
|
||||||
|
|
||||||
|
using (var archive = new ZipArchive(ms, ZipArchiveMode.Create, leaveOpen: true))
|
||||||
|
{
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
if (!file.Exists)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Path relativo rispetto a rootDir -> mantiene le directory nello zip
|
||||||
|
var relativePath = Path.GetRelativePath(rootDir, file.FullName);
|
||||||
|
|
||||||
|
// Zip usa "/" come separatore: normalizziamo per compatibilità
|
||||||
|
var entryName = relativePath.Replace('\\', '/');
|
||||||
|
|
||||||
|
var entry = archive.CreateEntry(entryName, CompressionLevel.Optimal);
|
||||||
|
|
||||||
|
using var entryStream = entry.Open();
|
||||||
|
using var fileStream = file.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||||
|
|
||||||
|
fileStream.CopyTo(entryStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ms.ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
23
SteUp.Maui/Core/Utility/UtilityFile.cs
Normal file
23
SteUp.Maui/Core/Utility/UtilityFile.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using SteUp.Shared.Core.Dto;
|
||||||
|
|
||||||
|
namespace SteUp.Maui.Core.Utility;
|
||||||
|
|
||||||
|
public static class UtilityFile
|
||||||
|
{
|
||||||
|
public static async Task<AttachedDto> ConvertToDto(FileResult file, AttachedDto.TypeAttached type)
|
||||||
|
{
|
||||||
|
var stream = await file.OpenReadAsync();
|
||||||
|
using var ms = new MemoryStream();
|
||||||
|
await stream.CopyToAsync(ms);
|
||||||
|
|
||||||
|
return new AttachedDto
|
||||||
|
{
|
||||||
|
Name = file.FileName,
|
||||||
|
Path = file.FullPath,
|
||||||
|
MimeType = file.ContentType,
|
||||||
|
DimensionBytes = ms.Length,
|
||||||
|
FileBytes = ms.ToArray(),
|
||||||
|
Type = type
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
37
SteUp.Maui/Core/UtilityException/GlobalExceptionHandler.cs
Normal file
37
SteUp.Maui/Core/UtilityException/GlobalExceptionHandler.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace SteUp.Maui.Core.UtilityException;
|
||||||
|
|
||||||
|
public static class GlobalExceptionHandler
|
||||||
|
{
|
||||||
|
public static void Register(ILogger logger)
|
||||||
|
{
|
||||||
|
AppDomain.CurrentDomain.UnhandledException += (_, args) =>
|
||||||
|
{
|
||||||
|
var ex = args.ExceptionObject as Exception;
|
||||||
|
logger.LogCritical(ex, "UnhandledException (AppDomain) — IsTerminating: {t}", args.IsTerminating);
|
||||||
|
};
|
||||||
|
|
||||||
|
TaskScheduler.UnobservedTaskException += (_, args) =>
|
||||||
|
{
|
||||||
|
logger.LogCritical(args.Exception, "UnobservedTaskException");
|
||||||
|
args.SetObserved();
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ANDROID
|
||||||
|
Android.Runtime.AndroidEnvironment.UnhandledExceptionRaiser += (_, args) =>
|
||||||
|
{
|
||||||
|
logger.LogCritical(args.Exception, "Android UnhandledException");
|
||||||
|
args.Handled = true;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if IOS || MACCATALYST
|
||||||
|
ObjCRuntime.Runtime.MarshalManagedException += (_, args) =>
|
||||||
|
{
|
||||||
|
logger.LogCritical(args.Exception, "iOS MarshalManagedException");
|
||||||
|
args.ExceptionMode = ObjCRuntime.MarshalManagedExceptionMode.UnwindNativeCode;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,6 +46,7 @@ namespace SteUp.Maui
|
|||||||
builder.RegisterSystemService();
|
builder.RegisterSystemService();
|
||||||
builder.RegisterDbServices();
|
builder.RegisterDbServices();
|
||||||
builder.RegisterMessageServices();
|
builder.RegisterMessageServices();
|
||||||
|
builder.RegisterLoggerServices();
|
||||||
|
|
||||||
return builder.Build();
|
return builder.Build();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
@using CommunityToolkit.Mvvm.Messaging
|
@using CommunityToolkit.Mvvm.Messaging
|
||||||
@using SteUp.Shared.Core.Entities
|
@using SteUp.Shared.Components.SingleElements.MessageBox
|
||||||
@using SteUp.Shared.Core.Interface.IntegryApi
|
@using SteUp.Shared.Core.Enum
|
||||||
@using SteUp.Shared.Core.Interface.System.Network
|
|
||||||
@using SteUp.Shared.Core.Messages.Ispezione
|
@using SteUp.Shared.Core.Messages.Ispezione
|
||||||
@using SteUp.Shared.Core.Messages.Scheda
|
@using SteUp.Shared.Core.Messages.Scheda
|
||||||
@inject INetworkService NetworkService
|
@inject INetworkService NetworkService
|
||||||
@@ -40,18 +39,18 @@
|
|||||||
Size="Size.Medium" IconSize="Size.Medium">
|
Size="Size.Medium" IconSize="Size.Medium">
|
||||||
@if (SchedaVisible)
|
@if (SchedaVisible)
|
||||||
{
|
{
|
||||||
|
<MudFabMenuItem Disabled="!NetworkService.IsNetworkAvailable()" OnClick="@NewScheda"
|
||||||
|
Label="Nuova scheda" Color="Color.Surface"/>
|
||||||
|
|
||||||
if (ShowCompleteInspection)
|
if (ShowCompleteInspection)
|
||||||
{
|
{
|
||||||
<MudFabMenuItem Disabled="!NetworkService.IsNetworkAvailable()" OnClick="@CompleteInspection"
|
<MudFabMenuItem Disabled="!NetworkService.IsNetworkAvailable()" OnClick="@CompleteInspection"
|
||||||
Label="Concludi ispezione" Color="Color.Surface"/>
|
Label="Concludi ispezione" Color="Color.Surface"/>
|
||||||
}
|
}
|
||||||
|
|
||||||
<MudFabMenuItem Disabled="!NetworkService.IsNetworkAvailable()" OnClick="@NewScheda"
|
|
||||||
Label="Nuova scheda" Color="Color.Surface"/>
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudFabMenuItem Disabled="!NetworkService.IsNetworkAvailable()" OnClick="@NewActivity"
|
<MudFabMenuItem Disabled="!NetworkService.IsNetworkAvailable()" OnClick="@NewInspection"
|
||||||
Label="Nuova ispezione" Color="Color.Surface"/>
|
Label="Nuova ispezione" Color="Color.Surface"/>
|
||||||
}
|
}
|
||||||
</MudFabMenu>
|
</MudFabMenu>
|
||||||
@@ -59,6 +58,9 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<ConfirmMessageBox @ref="_messageBox" NoText="No" YesText="Si" YesColor="Color.Primary"
|
||||||
|
Message="Completando l'ispezione non sarà più possibile editarla o aggiungere ulteriori segnalazioni. Procedere?"/>
|
||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
private bool IsVisible { get; set; } = true;
|
private bool IsVisible { get; set; } = true;
|
||||||
@@ -66,6 +68,8 @@
|
|||||||
private bool ShowCompleteInspection { get; set; }
|
private bool ShowCompleteInspection { get; set; }
|
||||||
private bool SchedaVisible { get; set; }
|
private bool SchedaVisible { get; set; }
|
||||||
|
|
||||||
|
private ConfirmMessageBox _messageBox = null!;
|
||||||
|
|
||||||
protected override Task OnInitializedAsync()
|
protected override Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
NavigationManager.LocationChanged += (_, args) =>
|
NavigationManager.LocationChanged += (_, args) =>
|
||||||
@@ -82,23 +86,42 @@
|
|||||||
|
|
||||||
IsVisible = newIsVisible;
|
IsVisible = newIsVisible;
|
||||||
PlusVisible = newPlusVisible;
|
PlusVisible = newPlusVisible;
|
||||||
|
|
||||||
|
if (location.EqualsIgnoreCase("ispezione"))
|
||||||
|
{
|
||||||
|
var ispezione = SteupDataService.InspectionPageState.Ispezione;
|
||||||
|
if (ispezione.Stato == StatusEnum.Completata) PlusVisible = false;
|
||||||
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
};
|
};
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NewActivity()
|
private async Task NewInspection()
|
||||||
{
|
{
|
||||||
_ = ModalHelper.OpenSelectShop(Dialog);
|
if (await SteupDataService.CanOpenNewInspection())
|
||||||
|
{
|
||||||
|
_ = Dialog.OpenSelectShop();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await Dialog.ShowWarning("Per aprire una nuova ispezione è necessario concludere prima tutte le ispezioni aperte più vecchie di 20 giorni!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CompleteInspection() =>
|
private async Task CompleteInspection()
|
||||||
Messenger.Send(new CompleteInspectionMessage());
|
{
|
||||||
|
var result = await _messageBox.ShowAsync();
|
||||||
|
|
||||||
|
if (result is true)
|
||||||
|
Messenger.Send(new CompleteInspectionMessage());
|
||||||
|
}
|
||||||
|
|
||||||
private async Task NewScheda()
|
private async Task NewScheda()
|
||||||
{
|
{
|
||||||
var ispezione = SteupDataService.InspectionPageState.Ispezione;
|
var ispezione = SteupDataService.InspectionPageState.Ispezione;
|
||||||
var modal = await ModalHelper.OpenFormScheda(Dialog, ispezione.CodMdep, ispezione.Data, true);
|
var modal = await Dialog.OpenFormScheda(ispezione.CodMdep, ispezione.Data, true);
|
||||||
|
|
||||||
if (modal is { Canceled: false })
|
if (modal is { Canceled: false })
|
||||||
Messenger.Send(new NewSchedaMessage());
|
Messenger.Send(new NewSchedaMessage());
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@page "/ispezione"
|
@page "/ispezione"
|
||||||
|
@using Microsoft.Extensions.Logging
|
||||||
@using SteUp.Shared.Components.Layout
|
@using SteUp.Shared.Components.Layout
|
||||||
@using SteUp.Shared.Components.Layout.Overlay
|
@using SteUp.Shared.Components.Layout.Overlay
|
||||||
@using SteUp.Shared.Components.SingleElements.Card
|
@using SteUp.Shared.Components.SingleElements.Card
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
@using SteUp.Shared.Core.Enum
|
@using SteUp.Shared.Core.Enum
|
||||||
@using SteUp.Shared.Core.Interface.IntegryApi
|
@using SteUp.Shared.Core.Interface.IntegryApi
|
||||||
@using SteUp.Shared.Core.Interface.LocalDb
|
@using SteUp.Shared.Core.Interface.LocalDb
|
||||||
|
@using SteUp.Shared.Core.Interface.System
|
||||||
@using SteUp.Shared.Core.Messages.Ispezione
|
@using SteUp.Shared.Core.Messages.Ispezione
|
||||||
@using SteUp.Shared.Core.Messages.Scheda
|
@using SteUp.Shared.Core.Messages.Scheda
|
||||||
@inject NewSchedaService NewScheda
|
@inject NewSchedaService NewScheda
|
||||||
@@ -14,6 +16,8 @@
|
|||||||
@inject IIspezioniService IspezioniService
|
@inject IIspezioniService IspezioniService
|
||||||
@inject IDialogService Dialog
|
@inject IDialogService Dialog
|
||||||
@inject IIntegrySteupService IntegrySteupService
|
@inject IIntegrySteupService IntegrySteupService
|
||||||
|
@inject IFileManager FileManager
|
||||||
|
@inject ILogger<IspezionePage> Logger
|
||||||
@implements IDisposable
|
@implements IDisposable
|
||||||
|
|
||||||
<HeaderLayout Title="Ispezione" BackTo="Indietro" Back="true"/>
|
<HeaderLayout Title="Ispezione" BackTo="Indietro" Back="true"/>
|
||||||
@@ -35,25 +39,28 @@
|
|||||||
@($"{group.Value.Count} sched{(group.Value.Count == 1 ? "a" : "e")}")
|
@($"{group.Value.Count} sched{(group.Value.Count == 1 ? "a" : "e")}")
|
||||||
</MudChip>
|
</MudChip>
|
||||||
</div>
|
</div>
|
||||||
<div class="action-scheda-group">
|
@if (SteupDataService.InspectionPageState.Ispezione.Stato != StatusEnum.Completata)
|
||||||
@if (NetworkService.IsNetworkAvailable())
|
{
|
||||||
{
|
<div class="action-scheda-group">
|
||||||
<MudFab StartIcon="@Icons.Material.Rounded.Add"
|
@if (NetworkService.IsNetworkAvailable())
|
||||||
Color="Color.Warning" Size="Size.Small"
|
{
|
||||||
OnClick="@(() => CreateNewScheda(group.Key))"/>
|
<MudFab StartIcon="@Icons.Material.Rounded.Add"
|
||||||
|
Color="Color.Warning" Size="Size.Small"
|
||||||
|
OnClick="@(() => CreateNewScheda(group.Key))"/>
|
||||||
|
|
||||||
<MudFab StartIcon="@Icons.Material.Rounded.CloudSync" Label="Esporta reparto"
|
<MudFab StartIcon="@Icons.Material.Rounded.CloudSync" Label="Esporta reparto"
|
||||||
Color="Color.Success" Size="Size.Small"
|
Color="Color.Success" Size="Size.Small"
|
||||||
OnClick="@(() => ExportReparto(group.Key))"/>
|
OnClick="@(() => ExportReparto(group.Key))"/>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudFab StartIcon="@Icons.Material.Rounded.Add"
|
<MudFab StartIcon="@Icons.Material.Rounded.Add"
|
||||||
Label="@($"Nuova scheda su {group.Key.Descrizione}")"
|
Label="@($"Nuova scheda su {group.Key.Descrizione}")"
|
||||||
Color="Color.Warning" Size="Size.Medium"
|
Color="Color.Warning" Size="Size.Medium"
|
||||||
OnClick="@(() => CreateNewScheda(group.Key))"/>
|
OnClick="@(() => CreateNewScheda(group.Key))"/>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</TitleContent>
|
</TitleContent>
|
||||||
<ChildContent>
|
<ChildContent>
|
||||||
@@ -61,8 +68,7 @@
|
|||||||
{
|
{
|
||||||
<SchedaCard Scheda="scheda" OnSchedaDeleted="OnSchedaDeleted"
|
<SchedaCard Scheda="scheda" OnSchedaDeleted="OnSchedaDeleted"
|
||||||
OnSchedaModified="OnSchedaModified"
|
OnSchedaModified="OnSchedaModified"
|
||||||
CodMdep="@SteupDataService.InspectionPageState.Ispezione.CodMdep"
|
Ispezione="@SteupDataService.InspectionPageState.Ispezione"/>
|
||||||
Data="@SteupDataService.InspectionPageState.Ispezione.Data"/>
|
|
||||||
}
|
}
|
||||||
</ChildContent>
|
</ChildContent>
|
||||||
</MudExpansionPanel>
|
</MudExpansionPanel>
|
||||||
@@ -114,7 +120,48 @@
|
|||||||
|
|
||||||
var ispezione = SteupDataService.InspectionPageState.Ispezione;
|
var ispezione = SteupDataService.InspectionPageState.Ispezione;
|
||||||
|
|
||||||
SteupDataService.InspectionPageState.Ispezione.Stato = StatusEnum.Completata;
|
foreach (var scheda in ispezione.Schede.Where(x => x.ActivityId == null))
|
||||||
|
{
|
||||||
|
var apiResponse = await IntegrySteupService.SaveScheda(
|
||||||
|
new SaveRequestDto
|
||||||
|
{
|
||||||
|
LocalIdScheda = scheda.Id,
|
||||||
|
ActivityTypeId = scheda.ActivityTypeId,
|
||||||
|
CodJfas = scheda.CodJfas,
|
||||||
|
CodMdep = ispezione.CodMdep,
|
||||||
|
DataCreazione = ispezione.Data,
|
||||||
|
Note = scheda.Note,
|
||||||
|
PersonaRif = scheda.Responsabile,
|
||||||
|
Barcodes = scheda.Articoli.ConvertAll(x => x.Barcode),
|
||||||
|
Scandeza = (ScadenzaEnum)scheda.Scadenza,
|
||||||
|
ParentActivityId = scheda.Ispezione?.ActivityId
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (apiResponse == null) continue;
|
||||||
|
|
||||||
|
scheda.ActivityId = apiResponse.ActivityIdScheda;
|
||||||
|
await IspezioniService.UpdateSchedaAsync(scheda);
|
||||||
|
|
||||||
|
await IspezioniService.UpdateActivityIdIspezioneAsync(
|
||||||
|
ispezione.CodMdep,
|
||||||
|
ispezione.Data,
|
||||||
|
ispezione.Rilevatore,
|
||||||
|
apiResponse.ActivityIdIspezione
|
||||||
|
);
|
||||||
|
|
||||||
|
if (scheda.ImageNames == null) continue;
|
||||||
|
|
||||||
|
var fileList = (await FileManager.GetInspectionFiles(ispezione, scheda.ImageNames))?
|
||||||
|
.Where(x => x.ToUpload).ToList();
|
||||||
|
|
||||||
|
if (fileList == null) continue;
|
||||||
|
|
||||||
|
foreach (var file in fileList)
|
||||||
|
{
|
||||||
|
await IntegrySteupService.UploadFile(scheda.ActivityId!, file.FileBytes!, file.Name!);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await IntegrySteupService.CompleteInspection(ispezione.ActivityId!);
|
await IntegrySteupService.CompleteInspection(ispezione.ActivityId!);
|
||||||
await IspezioniService.UpdateStatoIspezioneAsync(
|
await IspezioniService.UpdateStatoIspezioneAsync(
|
||||||
@@ -123,6 +170,8 @@
|
|||||||
ispezione.Rilevatore,
|
ispezione.Rilevatore,
|
||||||
StatusEnum.Completata
|
StatusEnum.Completata
|
||||||
);
|
);
|
||||||
|
|
||||||
|
SteupDataService.InspectionPageState.Ispezione.Stato = StatusEnum.Completata;
|
||||||
|
|
||||||
await InvokeAsync(() =>
|
await InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
@@ -133,14 +182,14 @@
|
|||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e.Message);
|
Console.WriteLine(e.Message);
|
||||||
|
|
||||||
await InvokeAsync(() =>
|
await InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
VisibleOverlay = false;
|
VisibleOverlay = false;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
OnError(e.Message);
|
OnError(e, e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,8 +222,7 @@
|
|||||||
|
|
||||||
private async Task CreateNewScheda(JtbFasiDto jtbFasi)
|
private async Task CreateNewScheda(JtbFasiDto jtbFasi)
|
||||||
{
|
{
|
||||||
var modal = await ModalHelper.OpenFormScheda(
|
var modal = await Dialog.OpenFormScheda(
|
||||||
Dialog,
|
|
||||||
SteupDataService.InspectionPageState.Ispezione.CodMdep,
|
SteupDataService.InspectionPageState.Ispezione.CodMdep,
|
||||||
SteupDataService.InspectionPageState.Ispezione.Data,
|
SteupDataService.InspectionPageState.Ispezione.Data,
|
||||||
true,
|
true,
|
||||||
@@ -240,11 +288,12 @@
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnError(string? errorMessage)
|
private void OnError(Exception? e, string? errorMessage)
|
||||||
{
|
{
|
||||||
|
if (e != null) Logger.LogError(e, errorMessage);
|
||||||
if (errorMessage == null) return;
|
if (errorMessage == null) return;
|
||||||
|
|
||||||
_ = ModalHelper.ShowError(Dialog, errorMessage);
|
_ = Dialog.ShowError(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IDisposable.Dispose()
|
void IDisposable.Dispose()
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
private async Task LoadData()
|
private async Task LoadData()
|
||||||
{
|
{
|
||||||
Ispezioni = await IspezioniService.GetAllIspezioniWithSchedeAsync();
|
Ispezioni = await IspezioniService.GetAllIspezioniWithSchedeAsync(UserSession.User.Username);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClickIspezione(Ispezione ispezione)
|
private void OnClickIspezione(Ispezione ispezione)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@page "/login"
|
@page "/login"
|
||||||
|
@using Microsoft.Extensions.Logging
|
||||||
@using SteUp.Shared.Components.Layout.Spinner
|
@using SteUp.Shared.Components.Layout.Spinner
|
||||||
@using SteUp.Shared.Core.BarcodeReader.Contracts
|
@using SteUp.Shared.Core.BarcodeReader.Contracts
|
||||||
@using SteUp.Shared.Core.Interface.System
|
@using SteUp.Shared.Core.Interface.System
|
||||||
@@ -7,6 +8,7 @@
|
|||||||
@inject AppAuthenticationStateProvider AuthenticationStateProvider
|
@inject AppAuthenticationStateProvider AuthenticationStateProvider
|
||||||
@inject IGenericSystemService GenericSystemService
|
@inject IGenericSystemService GenericSystemService
|
||||||
@inject IBarcodeManager BarcodeManager
|
@inject IBarcodeManager BarcodeManager
|
||||||
|
@inject ILogger<LoginPage> Logger
|
||||||
|
|
||||||
@if (Spinner)
|
@if (Spinner)
|
||||||
{
|
{
|
||||||
@@ -100,12 +102,13 @@ else
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
ErrorMessage = e.Message;
|
||||||
|
Logger.LogError(e, ErrorMessage);
|
||||||
Console.WriteLine(e.Message);
|
Console.WriteLine(e.Message);
|
||||||
|
|
||||||
Spinner = false;
|
Spinner = false;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
|
||||||
ErrorMessage = e.Message;
|
|
||||||
_attemptFailed = true;
|
_attemptFailed = true;
|
||||||
Console.WriteLine(e);
|
Console.WriteLine(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
@page "/user"
|
@page "/user"
|
||||||
@attribute [Authorize]
|
@attribute [Authorize]
|
||||||
@using SteUp.Shared.Components.Layout
|
@using SteUp.Shared.Components.Layout
|
||||||
|
@using SteUp.Shared.Components.Layout.Overlay
|
||||||
@using SteUp.Shared.Components.SingleElements
|
@using SteUp.Shared.Components.SingleElements
|
||||||
@using SteUp.Shared.Core.Authorization.Enum
|
@using SteUp.Shared.Core.Authorization.Enum
|
||||||
@using SteUp.Shared.Core.Interface.System.Network
|
@using SteUp.Shared.Core.Dto
|
||||||
|
@using SteUp.Shared.Core.Interface.IntegryApi
|
||||||
|
@using SteUp.Shared.Core.Interface.System
|
||||||
@using SteUp.Shared.Core.Services
|
@using SteUp.Shared.Core.Services
|
||||||
@using SteUp.Shared.Core.Utility
|
@using SteUp.Shared.Core.Utility
|
||||||
@inject AppAuthenticationStateProvider AuthenticationStateProvider
|
@inject AppAuthenticationStateProvider AuthenticationStateProvider
|
||||||
@inject INetworkService NetworkService
|
@inject INetworkService NetworkService
|
||||||
|
@inject IGenericSystemService GenericSystemService
|
||||||
|
@inject IFileManager FileManager
|
||||||
|
@inject IIntegryApiService IntegryApiService
|
||||||
|
|
||||||
<HeaderLayout Title="Profilo"/>
|
<HeaderLayout Title="Profilo"/>
|
||||||
|
|
||||||
@@ -62,19 +68,30 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="container-button ripple-container mud-elevation-1">
|
||||||
|
<MudButton Class="button-settings red-icon"
|
||||||
|
FullWidth="true"
|
||||||
|
StartIcon="@Icons.Material.Rounded.UploadFile"
|
||||||
|
Size="Size.Medium"
|
||||||
|
OnClick="@ExportLog"
|
||||||
|
Variant="Variant.Outlined">
|
||||||
|
Esporta log
|
||||||
|
</MudButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="container-button mud-elevation-1">
|
<div class="container-button ripple-container mud-elevation-1">
|
||||||
<MudButton Class="button-settings green-icon"
|
<MudButton Class="button-settings green-icon"
|
||||||
FullWidth="true"
|
FullWidth="true"
|
||||||
StartIcon="@Icons.Material.Outlined.Sync"
|
StartIcon="@Icons.Material.Outlined.Sync"
|
||||||
Size="Size.Medium"
|
Size="Size.Medium"
|
||||||
OnClick="@UpdateDb"
|
OnClick="@UpdateDb"
|
||||||
Variant="Variant.Outlined">
|
Variant="Variant.Outlined">
|
||||||
Sincronizza ispezioni
|
Sincronizza ispezioni esportate
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container-button mud-elevation-1">
|
<div class="container-button ripple-container mud-elevation-1">
|
||||||
<MudButton Class="button-settings exit"
|
<MudButton Class="button-settings exit"
|
||||||
FullWidth="true"
|
FullWidth="true"
|
||||||
Color="Color.Error"
|
Color="Color.Error"
|
||||||
@@ -89,8 +106,11 @@
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<SpinnerOverlay VisibleOverlay="VisibleOverlay"/>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private bool IsLoggedIn { get; set; }
|
private bool IsLoggedIn { get; set; }
|
||||||
|
private bool VisibleOverlay { get; set; }
|
||||||
private string? CodHash { get; set; } = "";
|
private string? CodHash { get; set; } = "";
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
@@ -100,8 +120,41 @@
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateDb()
|
private async Task ExportLog()
|
||||||
{
|
{
|
||||||
|
VisibleOverlay = true;
|
||||||
|
StateHasChanged();
|
||||||
|
|
||||||
|
var profiloAzienda = LocalStorage.GetString("codHash");
|
||||||
|
|
||||||
|
var email = new SendEmailDto
|
||||||
|
{
|
||||||
|
FromName = "Integry Log",
|
||||||
|
To = "developer@integry.it",
|
||||||
|
Subject = $"SteUP - Log del {DateTime.Today:d} di {UserSession.User.Username}",
|
||||||
|
IsHtml = true,
|
||||||
|
MsgText = $"Username: <b>{UserSession.User.Username}</b><br/>" +
|
||||||
|
$"Profilo azienda: <b>{profiloAzienda}</b><br/>" +
|
||||||
|
$"ProfileDb: <b>{UserSession.ProfileDb}</b><br/>" +
|
||||||
|
$"Versione app: <b>{GenericSystemService.GetCurrentAppVersion()}</b>",
|
||||||
|
Attachments = FileManager.GetFileForExport()
|
||||||
|
};
|
||||||
|
|
||||||
|
await IntegryApiService.SendEmail(email);
|
||||||
|
|
||||||
|
VisibleOverlay = false;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateDb()
|
||||||
|
{
|
||||||
|
VisibleOverlay = true;
|
||||||
|
StateHasChanged();
|
||||||
|
|
||||||
|
await SteupDataService.CheckAndUpdateStatus();
|
||||||
|
|
||||||
|
VisibleOverlay = false;
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Logout()
|
private async Task Logout()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
@using SteUp.Shared.Core.BarcodeReader.Contracts
|
@using SteUp.Shared.Core.BarcodeReader.Contracts
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IBarcodeManager BarcodeManager
|
@inject IBarcodeManager BarcodeManager
|
||||||
|
@inject AuthenticationStateProvider AuthStateProvider
|
||||||
|
|
||||||
<ErrorBoundary @ref="ErrorBoundary">
|
<ErrorBoundary @ref="ErrorBoundary">
|
||||||
<ChildContent>
|
<ChildContent>
|
||||||
@@ -56,8 +57,13 @@
|
|||||||
{
|
{
|
||||||
LoadData = true;
|
LoadData = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
|
||||||
await SteupDataService.Init();
|
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
|
||||||
|
var user = authState.User;
|
||||||
|
|
||||||
|
if (user.Identity is { IsAuthenticated: true })
|
||||||
|
await SteupDataService.Init();
|
||||||
|
|
||||||
BarcodeManager.Init();
|
BarcodeManager.Init();
|
||||||
|
|
||||||
LoadData = false;
|
LoadData = false;
|
||||||
|
|||||||
@@ -5,9 +5,11 @@
|
|||||||
@using SteUp.Shared.Core.Enum
|
@using SteUp.Shared.Core.Enum
|
||||||
@using SteUp.Shared.Core.Interface.IntegryApi
|
@using SteUp.Shared.Core.Interface.IntegryApi
|
||||||
@using SteUp.Shared.Core.Interface.LocalDb
|
@using SteUp.Shared.Core.Interface.LocalDb
|
||||||
|
@using SteUp.Shared.Core.Interface.System
|
||||||
@inject IIspezioniService IspezioniService
|
@inject IIspezioniService IspezioniService
|
||||||
@inject IIntegrySteupService IntegrySteupService
|
@inject IIntegrySteupService IntegrySteupService
|
||||||
@inject IDialogService Dialog
|
@inject IDialogService Dialog
|
||||||
|
@inject IFileManager FileManager
|
||||||
|
|
||||||
<div class="scheda-card">
|
<div class="scheda-card">
|
||||||
<div class="scheda-body-section">
|
<div class="scheda-body-section">
|
||||||
@@ -27,58 +29,87 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="scheda-card-action">
|
<div class="scheda-card-action">
|
||||||
@if (NetworkService.IsNetworkAvailable())
|
@if (Ispezione.Stato != StatusEnum.Completata)
|
||||||
{
|
{
|
||||||
<MudFab Color="Color.Info" Size="Size.Small" StartIcon="@Icons.Material.Rounded.Edit" OnClick="@UpdateScheda"/>
|
if (NetworkService.IsNetworkAvailable())
|
||||||
<MudFab Color="Color.Error" Size="Size.Small" StartIcon="@Icons.Material.Rounded.Delete" OnClick="@DeleteScheda"/>
|
{
|
||||||
<MudFab Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Rounded.CloudSync" OnClick="@ExportScheda"/>
|
<MudFab Color="Color.Info" Size="Size.Small" StartIcon="@Icons.Material.Rounded.Edit"
|
||||||
|
OnClick="@UpdateScheda"/>
|
||||||
|
<MudFab Color="Color.Error" Size="Size.Small" StartIcon="@Icons.Material.Rounded.Delete"
|
||||||
|
OnClick="@DeleteScheda"/>
|
||||||
|
<MudFab Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Rounded.CloudSync"
|
||||||
|
OnClick="@ExportScheda"/>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<MudFab Color="Color.Info" Size="Size.Small" StartIcon="@Icons.Material.Rounded.Edit"
|
||||||
|
OnClick="@UpdateScheda"/>
|
||||||
|
<MudFab Color="Color.Error" Size="Size.Small" StartIcon="@Icons.Material.Rounded.Delete"
|
||||||
|
OnClick="@DeleteScheda"/>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Rounded.Edit"
|
<MudFab Color="Color.Info" Size="Size.Small" StartIcon="@Icons.Material.Rounded.RemoveRedEye"
|
||||||
Color="Color.Info" Size="Size.Small" OnClick="@UpdateScheda">
|
OnClick="@ViewScheda"/>
|
||||||
Modifica
|
<MudFab Color="Color.Success" Size="Size.Small" StartIcon="@Icons.Material.Rounded.CloudSync"
|
||||||
</MudButton>
|
OnClick="@ExportImg"/>
|
||||||
<MudButton Variant="Variant.Filled" StartIcon="@Icons.Material.Rounded.Delete"
|
|
||||||
Color="Color.Error" Size="Size.Small" OnClick="@DeleteScheda">
|
|
||||||
Cancella
|
|
||||||
</MudButton>
|
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SpinnerOverlay VisibleOverlay="VisibleOverlay"/>
|
<SpinnerOverlay VisibleOverlay="VisibleOverlay"/>
|
||||||
<ConfirmDeleteMessageBox @ref="_deleteMessageBox" Message="Confermi la cancellazione della scheda corrente?"/>
|
<ConfirmMessageBox @ref="_messageBox" YesText="Cancella" YesColor="Color.Error"
|
||||||
|
Message="Confermi la cancellazione della scheda corrente?"/>
|
||||||
|
|
||||||
@code{
|
@code{
|
||||||
[Parameter] public string CodMdep { get; set; } = string.Empty;
|
[Parameter] public Ispezione Ispezione { get; set; } = new();
|
||||||
[Parameter] public DateTime Data { get; set; }
|
|
||||||
[Parameter] public required Scheda Scheda { get; set; }
|
[Parameter] public required Scheda Scheda { get; set; }
|
||||||
[Parameter] public EventCallback<Scheda> OnSchedaModified { get; set; }
|
[Parameter] public EventCallback<Scheda> OnSchedaModified { get; set; }
|
||||||
[Parameter] public EventCallback<Scheda> OnSchedaDeleted { get; set; }
|
[Parameter] public EventCallback<Scheda> OnSchedaDeleted { get; set; }
|
||||||
|
|
||||||
private bool VisibleOverlay { get; set; }
|
private bool VisibleOverlay { get; set; }
|
||||||
|
|
||||||
private ConfirmDeleteMessageBox _deleteMessageBox = null!;
|
private ConfirmMessageBox _messageBox = null!;
|
||||||
|
|
||||||
private async Task UpdateScheda()
|
private async Task UpdateScheda()
|
||||||
{
|
{
|
||||||
var modal = await ModalHelper.OpenFormScheda(Dialog, CodMdep, Data, false, Scheda);
|
var modal = await Dialog.OpenFormScheda(Ispezione.CodMdep, Ispezione.Data, false, Scheda);
|
||||||
if (modal is { Canceled: false, Data: Scheda scheda }) await OnSchedaModified.InvokeAsync(scheda);
|
if (modal is { Canceled: false, Data: Scheda scheda }) await OnSchedaModified.InvokeAsync(scheda);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteScheda()
|
private async Task DeleteScheda()
|
||||||
{
|
{
|
||||||
var result = await _deleteMessageBox.ShowAsync();
|
var result = await _messageBox.ShowAsync();
|
||||||
|
|
||||||
if (result is true)
|
if (result is true)
|
||||||
{
|
{
|
||||||
|
VisibleOverlay = true;
|
||||||
|
StateHasChanged();
|
||||||
|
|
||||||
|
if (Scheda.ActivityId != null)
|
||||||
|
await IntegrySteupService.DeleteScheda(Scheda.ActivityId);
|
||||||
|
|
||||||
|
if (Scheda.ImageNames != null)
|
||||||
|
{
|
||||||
|
foreach (var fileName in Scheda.ImageNames)
|
||||||
|
{
|
||||||
|
FileManager.RemoveInspectionFile(Ispezione, fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var deleteScheda = await IspezioniService.DeleteSchedaAsync(Scheda.Id);
|
var deleteScheda = await IspezioniService.DeleteSchedaAsync(Scheda.Id);
|
||||||
if (deleteScheda) await OnSchedaDeleted.InvokeAsync(Scheda);
|
if (deleteScheda) await OnSchedaDeleted.InvokeAsync(Scheda);
|
||||||
|
|
||||||
|
VisibleOverlay = false;
|
||||||
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ViewScheda() =>
|
||||||
|
_ = Dialog.OpenFormScheda(Ispezione.CodMdep, Ispezione.Data, false, Scheda, true);
|
||||||
|
|
||||||
private async Task ExportScheda()
|
private async Task ExportScheda()
|
||||||
{
|
{
|
||||||
VisibleOverlay = true;
|
VisibleOverlay = true;
|
||||||
@@ -90,8 +121,8 @@
|
|||||||
LocalIdScheda = Scheda.Id,
|
LocalIdScheda = Scheda.Id,
|
||||||
ActivityTypeId = Scheda.ActivityTypeId,
|
ActivityTypeId = Scheda.ActivityTypeId,
|
||||||
CodJfas = Scheda.CodJfas,
|
CodJfas = Scheda.CodJfas,
|
||||||
CodMdep = CodMdep,
|
CodMdep = Ispezione.CodMdep,
|
||||||
DataCreazione = Data,
|
DataCreazione = Ispezione.Data,
|
||||||
Note = Scheda.Note,
|
Note = Scheda.Note,
|
||||||
PersonaRif = Scheda.Responsabile,
|
PersonaRif = Scheda.Responsabile,
|
||||||
Barcodes = Scheda.Articoli.ConvertAll(x => x.Barcode),
|
Barcodes = Scheda.Articoli.ConvertAll(x => x.Barcode),
|
||||||
@@ -99,13 +130,13 @@
|
|||||||
ParentActivityId = Scheda.Ispezione?.ActivityId
|
ParentActivityId = Scheda.Ispezione?.ActivityId
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (apiResponse != null)
|
if (apiResponse != null)
|
||||||
{
|
{
|
||||||
Scheda.ActivityId = apiResponse.ActivityIdScheda;
|
Scheda.ActivityId = apiResponse.ActivityIdScheda;
|
||||||
SteupDataService.InspectionPageState.Ispezione.ActivityId = apiResponse.ActivityIdIspezione;
|
SteupDataService.InspectionPageState.Ispezione.ActivityId = apiResponse.ActivityIdIspezione;
|
||||||
|
|
||||||
await IspezioniService.UpdateActivityIdIspezioneAsync(CodMdep, Data,
|
await IspezioniService.UpdateActivityIdIspezioneAsync(Ispezione.CodMdep, Ispezione.Data,
|
||||||
UserSession.User.Username, apiResponse.ActivityIdIspezione
|
UserSession.User.Username, apiResponse.ActivityIdIspezione
|
||||||
);
|
);
|
||||||
await IspezioniService.UpdateActivityIdSchedaAsync(Scheda.Id, Scheda.ActivityId);
|
await IspezioniService.UpdateActivityIdSchedaAsync(Scheda.Id, Scheda.ActivityId);
|
||||||
@@ -115,4 +146,18 @@
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task ExportImg()
|
||||||
|
{
|
||||||
|
if (Scheda.ImageNames == null) return;
|
||||||
|
|
||||||
|
var fileList = (await FileManager.GetInspectionFiles(Ispezione, Scheda.ImageNames))?
|
||||||
|
.Where(x => x.ToUpload).ToList();
|
||||||
|
|
||||||
|
if (fileList == null) return;
|
||||||
|
|
||||||
|
foreach (var file in fileList)
|
||||||
|
{
|
||||||
|
await IntegrySteupService.UploadFile(Scheda.ActivityId!, file.FileBytes!, file.Name!);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<MudMessageBox @ref="_confirmDelete" Title="Attenzione!" CancelText="Annulla">
|
<MudMessageBox @ref="_confirmDelete" Title="Attenzione!" CancelText="@NoText">
|
||||||
<MessageContent>
|
<MessageContent>
|
||||||
@Message
|
@Message
|
||||||
</MessageContent>
|
</MessageContent>
|
||||||
<YesButton>
|
<YesButton>
|
||||||
<MudButton Size="Size.Small" Variant="Variant.Filled" Color="Color.Error">
|
<MudButton Size="Size.Small" Variant="Variant.Filled" Color="YesColor">
|
||||||
Cancella
|
@YesText
|
||||||
</MudButton>
|
</MudButton>
|
||||||
</YesButton>
|
</YesButton>
|
||||||
</MudMessageBox>
|
</MudMessageBox>
|
||||||
@@ -12,6 +12,9 @@
|
|||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
[Parameter] public string Message { get; set; } = string.Empty;
|
[Parameter] public string Message { get; set; } = string.Empty;
|
||||||
|
[Parameter] public string YesText { get; set; } = string.Empty;
|
||||||
|
[Parameter] public string NoText { get; set; } = "Annulla";
|
||||||
|
[Parameter] public Color YesColor { get; set; } = Color.Primary;
|
||||||
|
|
||||||
private MudMessageBox? _confirmDelete;
|
private MudMessageBox? _confirmDelete;
|
||||||
|
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
<div class="container container-modal">
|
@using Microsoft.Extensions.Logging
|
||||||
|
@inject ILogger<ExceptionModal> Logger
|
||||||
|
|
||||||
|
<div class="container container-modal">
|
||||||
<div class="c-modal">
|
<div class="c-modal">
|
||||||
<div class="exception-header mb-2">
|
<div class="exception-header mb-2">
|
||||||
<i class="ri-emotion-unhappy-line"></i>
|
<i class="ri-emotion-unhappy-line"></i>
|
||||||
@@ -43,6 +46,8 @@
|
|||||||
{
|
{
|
||||||
Message = Exception.Message;
|
Message = Exception.Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.LogError(Exception, "Errore nel componente Blazor: {Message}", Message);
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,19 @@
|
|||||||
<MudDialog OnBackdropClick="Cancel">
|
<MudDialog OnBackdropClick="Cancel">
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<div class="exception-header mb-2">
|
@if (IsWarning)
|
||||||
<i class="ri-emotion-unhappy-line"></i>
|
{
|
||||||
<span>Ops</span>
|
<div class="exception-header mb-2">
|
||||||
</div>
|
<i class="ri-error-warning-line warning-icon"></i>
|
||||||
|
<span>Attenzione</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<div class="exception-header mb-2">
|
||||||
|
<i class="ri-emotion-unhappy-line error-icon"></i>
|
||||||
|
<span>Ops</span>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
<div class="text">
|
<div class="text">
|
||||||
<code>@ErrorMessage</code>
|
<code>@ErrorMessage</code>
|
||||||
</div>
|
</div>
|
||||||
@@ -18,6 +28,7 @@
|
|||||||
@code {
|
@code {
|
||||||
[CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!;
|
[CascadingParameter] private IMudDialogInstance MudDialog { get; set; } = null!;
|
||||||
[Parameter] public string ErrorMessage { get; set; } = string.Empty;
|
[Parameter] public string ErrorMessage { get; set; } = string.Empty;
|
||||||
|
[Parameter] public bool IsWarning { get; set; }
|
||||||
|
|
||||||
private void Cancel() => MudDialog.Cancel();
|
private void Cancel() => MudDialog.Cancel();
|
||||||
}
|
}
|
||||||
@@ -8,9 +8,16 @@
|
|||||||
.exception-header > i {
|
.exception-header > i {
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-icon {
|
||||||
color: var(--bs-danger);
|
color: var(--bs-danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.warning-icon {
|
||||||
|
color: var(--bs-warning);
|
||||||
|
}
|
||||||
|
|
||||||
.exception-header > span {
|
.exception-header > span {
|
||||||
font-size: x-large;
|
font-size: x-large;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
@using SteUp.Shared.Components.Layout
|
@using Microsoft.Extensions.Logging
|
||||||
|
@using SteUp.Shared.Components.Layout
|
||||||
@using SteUp.Shared.Components.Layout.Overlay
|
@using SteUp.Shared.Components.Layout.Overlay
|
||||||
@using SteUp.Shared.Components.Layout.Spinner
|
@using SteUp.Shared.Components.Layout.Spinner
|
||||||
@using SteUp.Shared.Components.SingleElements.Card.ModalForm
|
@using SteUp.Shared.Components.SingleElements.Card.ModalForm
|
||||||
@@ -13,14 +14,15 @@
|
|||||||
@inject INetworkService NetworkService
|
@inject INetworkService NetworkService
|
||||||
@inject IDialogService Dialog
|
@inject IDialogService Dialog
|
||||||
@inject IIntegryApiService IntegryApiService
|
@inject IIntegryApiService IntegryApiService
|
||||||
@inject IAttachedService AttachedService
|
@inject IFileManager FileManager
|
||||||
@inject IIspezioniService IspezioniService
|
@inject IIspezioniService IspezioniService
|
||||||
@inject IIntegrySteupService IntegrySteupService
|
@inject IIntegrySteupService IntegrySteupService
|
||||||
@inject OnScannerService OnScannerService
|
@inject OnScannerService OnScannerService
|
||||||
|
@inject ILogger<ModalFormScheda> Logger
|
||||||
|
|
||||||
<MudDialog Class="customDialog-form">
|
<MudDialog Class="customDialog-form">
|
||||||
<DialogContent>
|
<DialogContent>
|
||||||
<MudForm @ref="_form">
|
<MudForm ReadOnly="ReadOnly" @ref="_form">
|
||||||
<HeaderLayout Cancel="true" OnCancel="@Cancel" LabelSave="@LabelSave"
|
<HeaderLayout Cancel="true" OnCancel="@Cancel" LabelSave="@LabelSave"
|
||||||
OnSave="Save" Title="Scheda"/>
|
OnSave="Save" Title="Scheda"/>
|
||||||
|
|
||||||
@@ -75,7 +77,7 @@
|
|||||||
}
|
}
|
||||||
<MudCardContent Class="image_card">
|
<MudCardContent Class="image_card">
|
||||||
<MudText Typo="Typo.subtitle1"><b>@item.p.Name</b></MudText>
|
<MudText Typo="Typo.subtitle1"><b>@item.p.Name</b></MudText>
|
||||||
@if (IsNew)
|
@if (item.p.ToUpload)
|
||||||
{
|
{
|
||||||
<MudIconButton Variant="Variant.Outlined"
|
<MudIconButton Variant="Variant.Outlined"
|
||||||
Icon="@Icons.Material.Rounded.Close"
|
Icon="@Icons.Material.Rounded.Close"
|
||||||
@@ -89,25 +91,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</CardFormModal>
|
</CardFormModal>
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="container-button ripple-container">
|
@if (!ReadOnly)
|
||||||
<MudButton Class="button-settings green-icon"
|
{
|
||||||
FullWidth="true"
|
<div class="container-button ripple-container">
|
||||||
StartIcon="@Icons.Material.Rounded.AttachFile"
|
<MudButton Class="button-settings green-icon"
|
||||||
Size="Size.Medium"
|
FullWidth="true"
|
||||||
OnClick="@OpenAddAttached"
|
StartIcon="@Icons.Material.Rounded.AttachFile"
|
||||||
Variant="Variant.Outlined">
|
Size="Size.Medium"
|
||||||
Aggiungi foto
|
OnClick="@OpenAddAttached"
|
||||||
</MudButton>
|
Variant="Variant.Outlined">
|
||||||
</div>
|
Aggiungi foto
|
||||||
|
</MudButton>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<CardFormModal Title="Articoli">
|
<CardFormModal Title="Articoli">
|
||||||
<div class="input-manual-barcode">
|
@if (!ReadOnly)
|
||||||
<MudTextField FullWidth="true" ReadOnly="IsView" T="string?" Variant="Variant.Text"
|
{
|
||||||
@bind-Value="ManualBarcode" Placeholder="Digita manualmente il codice"/>
|
<div class="input-manual-barcode">
|
||||||
<MudIconButton Color="Color.Primary" OnClick="@OnManualBarcodeSet"
|
<MudTextField FullWidth="true" T="string?" Variant="Variant.Text"
|
||||||
Size="Size.Small" Icon="@Icons.Material.Rounded.Send"/>
|
@bind-Value="ManualBarcode" Placeholder="Digita manualmente il codice"/>
|
||||||
</div>
|
<MudIconButton Color="Color.Primary" OnClick="@OnManualBarcodeSet"
|
||||||
|
Size="Size.Small" Icon="@Icons.Material.Rounded.Send"/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
@if (!Scheda.Articoli.IsNullOrEmpty())
|
@if (!Scheda.Articoli.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
<div class="art-list">
|
<div class="art-list">
|
||||||
@@ -129,7 +137,7 @@
|
|||||||
}
|
}
|
||||||
</CardFormModal>
|
</CardFormModal>
|
||||||
|
|
||||||
@if (!IsView)
|
@if (NetworkService.ConnectionAvailable && !ReadOnly)
|
||||||
{
|
{
|
||||||
<div class="container-button ripple-container">
|
<div class="container-button ripple-container">
|
||||||
<MudButton Class="button-settings red-icon"
|
<MudButton Class="button-settings red-icon"
|
||||||
@@ -190,10 +198,9 @@
|
|||||||
[Parameter] public required string CodMdep { get; set; }
|
[Parameter] public required string CodMdep { get; set; }
|
||||||
[Parameter] public required DateTime Data { get; set; }
|
[Parameter] public required DateTime Data { get; set; }
|
||||||
[Parameter] public bool IsNew { get; set; }
|
[Parameter] public bool IsNew { get; set; }
|
||||||
|
[Parameter] public bool ReadOnly { get; set; }
|
||||||
[Parameter] public Scheda Scheda { get; set; } = new();
|
[Parameter] public Scheda Scheda { get; set; } = new();
|
||||||
|
|
||||||
private bool IsView => !NetworkService.ConnectionAvailable;
|
|
||||||
|
|
||||||
private string? ManualBarcode { get; set; }
|
private string? ManualBarcode { get; set; }
|
||||||
|
|
||||||
//Overlay
|
//Overlay
|
||||||
@@ -234,7 +241,7 @@
|
|||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
var fileList = await AttachedService.GetInspectionFiles(
|
var fileList = await FileManager.GetInspectionFiles(
|
||||||
new Ispezione
|
new Ispezione
|
||||||
{
|
{
|
||||||
CodMdep = CodMdep,
|
CodMdep = CodMdep,
|
||||||
@@ -262,7 +269,7 @@
|
|||||||
SaveSchedaResponseDto? apiResponse = null;
|
SaveSchedaResponseDto? apiResponse = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!IsView)
|
if (NetworkService.ConnectionAvailable)
|
||||||
{
|
{
|
||||||
apiResponse = await IntegrySteupService.SaveScheda(
|
apiResponse = await IntegrySteupService.SaveScheda(
|
||||||
new SaveRequestDto
|
new SaveRequestDto
|
||||||
@@ -283,17 +290,19 @@
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e.Message);
|
var message = e.Message;
|
||||||
|
|
||||||
await ModalHelper.ShowError(Dialog, e.Message);
|
Logger.LogError(e, message);
|
||||||
|
Console.WriteLine(message);
|
||||||
|
await Dialog.ShowError(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsNew) await NewSave(apiResponse);
|
if (IsNew) await NewSave(apiResponse);
|
||||||
else await Update(apiResponse);
|
else await Update(apiResponse);
|
||||||
|
|
||||||
if (Scheda.ActivityId.IsValorized()) await UploadFile(Scheda.ActivityId!);
|
if (Scheda.ActivityId.IsValorized()) await UploadFile(Scheda);
|
||||||
|
|
||||||
await AttachedService.CleanTempStorageAsync();
|
await FileManager.CleanTempStorageAsync();
|
||||||
|
|
||||||
SuccessAnimation = true;
|
SuccessAnimation = true;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
@@ -309,7 +318,7 @@
|
|||||||
{
|
{
|
||||||
foreach (var attached in AttachedList!)
|
foreach (var attached in AttachedList!)
|
||||||
{
|
{
|
||||||
var fileNameAdded = await AttachedService.SaveInspectionFile(
|
var fileNameAdded = await FileManager.SaveInspectionFile(
|
||||||
new Ispezione
|
new Ispezione
|
||||||
{
|
{
|
||||||
CodMdep = CodMdep,
|
CodMdep = CodMdep,
|
||||||
@@ -352,7 +361,7 @@
|
|||||||
|
|
||||||
if (!attached.ToRemove)
|
if (!attached.ToRemove)
|
||||||
{
|
{
|
||||||
var fileNameAdded = await AttachedService.SaveInspectionFile(
|
var fileNameAdded = await FileManager.SaveInspectionFile(
|
||||||
ispezione,
|
ispezione,
|
||||||
attached.FileBytes!,
|
attached.FileBytes!,
|
||||||
attached.Name!
|
attached.Name!
|
||||||
@@ -363,7 +372,7 @@
|
|||||||
Scheda.ImageNames.Add(fileNameAdded);
|
Scheda.ImageNames.Add(fileNameAdded);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_ = AttachedService.RemoveInspectionFile(ispezione, attached.Name!);
|
_ = FileManager.RemoveInspectionFile(ispezione, attached.Name!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -376,7 +385,7 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UploadFile(string activityId)
|
private async Task UploadFile(Scheda scheda)
|
||||||
{
|
{
|
||||||
if (AttachedList.IsNullOrEmpty()) return;
|
if (AttachedList.IsNullOrEmpty()) return;
|
||||||
|
|
||||||
@@ -391,16 +400,23 @@
|
|||||||
{
|
{
|
||||||
if (file.FileBytes == null || file.Name == null) continue;
|
if (file.FileBytes == null || file.Name == null) continue;
|
||||||
|
|
||||||
await IntegrySteupService.UploadFile(activityId, file.FileBytes, file.Name);
|
await IntegrySteupService.UploadFile(scheda.ActivityId!, file.FileBytes, file.Name);
|
||||||
await AttachedService.MoveInspectionFileFromToUploadToFinal(ispezione, 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()
|
private async Task Cancel()
|
||||||
{
|
{
|
||||||
if (await CheckSavePreAction())
|
if (await CheckSavePreAction())
|
||||||
{
|
{
|
||||||
await AttachedService.CleanTempStorageAsync();
|
await FileManager.CleanTempStorageAsync();
|
||||||
DisposeMessage();
|
DisposeMessage();
|
||||||
MudDialog.Cancel();
|
MudDialog.Cancel();
|
||||||
}
|
}
|
||||||
@@ -474,7 +490,7 @@
|
|||||||
|
|
||||||
private async Task OpenAddAttached()
|
private async Task OpenAddAttached()
|
||||||
{
|
{
|
||||||
var result = await ModalHelper.OpenAddAttached(Dialog);
|
var result = await Dialog.OpenAddAttached();
|
||||||
if (result is not { Canceled: false, Data: List<AttachedDto> attachedList }) return;
|
if (result is not { Canceled: false, Data: List<AttachedDto> attachedList }) return;
|
||||||
|
|
||||||
OnLoading = true;
|
OnLoading = true;
|
||||||
@@ -498,7 +514,7 @@
|
|||||||
var a = attachedList[i];
|
var a = attachedList[i];
|
||||||
if (a.FileBytes is null || a.Name is null) continue;
|
if (a.FileBytes is null || a.Name is null) continue;
|
||||||
|
|
||||||
var (origUrl, thumbUrl) = await AttachedService.SaveAndCreateThumbAsync(a.FileBytes, a.Name);
|
var (origUrl, thumbUrl) = await FileManager.SaveAndCreateThumbAsync(a.FileBytes, a.Name);
|
||||||
|
|
||||||
await InvokeAsync(() =>
|
await InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
@@ -555,13 +571,13 @@
|
|||||||
TextLoading = null;
|
TextLoading = null;
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
|
||||||
OnError(e.Message);
|
OnError(e, e.Message);
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var modal = await ModalHelper.OpenSelectArt(Dialog, articoli);
|
var modal = await Dialog.OpenSelectArt(articoli);
|
||||||
|
|
||||||
await InvokeAsync(() =>
|
await InvokeAsync(() =>
|
||||||
{
|
{
|
||||||
@@ -614,7 +630,7 @@
|
|||||||
{
|
{
|
||||||
var activityDescriptions = await IntegryApiService.SuggestActivityDescription(Scheda.ActivityTypeId);
|
var activityDescriptions = await IntegryApiService.SuggestActivityDescription(Scheda.ActivityTypeId);
|
||||||
|
|
||||||
var modal = await ModalHelper.OpenSuggestActivityDescription(Dialog, activityDescriptions);
|
var modal = await Dialog.OpenSuggestActivityDescription(activityDescriptions);
|
||||||
|
|
||||||
if (modal is { Canceled: false, Data: not null })
|
if (modal is { Canceled: false, Data: not null })
|
||||||
Scheda.Note = modal.Data!.ToString();
|
Scheda.Note = modal.Data!.ToString();
|
||||||
@@ -668,7 +684,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OnError("Nessun articolo trovato");
|
OnError(null, "Nessun articolo trovato");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -682,19 +698,20 @@
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
});
|
});
|
||||||
|
|
||||||
OnError(e.Message);
|
OnError(e, e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnErrorScan(string? value) => OnError(value);
|
private void OnErrorScan(string? value) => OnError(new Exception(value), value);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void OnError(string? errorMessage)
|
private void OnError(Exception? e, string? errorMessage)
|
||||||
{
|
{
|
||||||
|
if (e != null) Logger.LogError(e, errorMessage);
|
||||||
if (errorMessage == null) return;
|
if (errorMessage == null) return;
|
||||||
|
|
||||||
_ = ModalHelper.ShowError(Dialog, errorMessage);
|
_ = Dialog.ShowError(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RemoveArt(string barcode)
|
private void RemoveArt(string barcode)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<div class="shop-header">
|
<div class="shop-header">
|
||||||
<div class="shop-title">
|
<div class="shop-title">
|
||||||
<MudText Typo="Typo.h5"><b>Seleziona il negozio</b></MudText>
|
<MudText Typo="Typo.h5"><b>Seleziona il negozio</b></MudText>
|
||||||
|
|
||||||
<MudIconButton Icon="@Icons.Material.Rounded.Close" Size="Size.Small" OnClick="@Cancel"/>
|
<MudIconButton Icon="@Icons.Material.Rounded.Close" Size="Size.Small" OnClick="@Cancel"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -67,19 +67,20 @@
|
|||||||
if (FilterText.IsNullOrEmpty())
|
if (FilterText.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
FilteredList = SteupDataService.PuntiVenditaList;
|
FilteredList = SteupDataService.PuntiVenditaList;
|
||||||
StateHasChanged();
|
}
|
||||||
return;
|
else
|
||||||
|
{
|
||||||
|
FilteredList = SteupDataService.PuntiVenditaList.FindAll(x =>
|
||||||
|
(x.Indirizzo != null && x.Indirizzo.ContainsIgnoreCase(FilterText!)) ||
|
||||||
|
(x.Descrizione != null && x.Descrizione.ContainsIgnoreCase(FilterText!)) ||
|
||||||
|
(x.CodMdep != null && x.CodMdep.ContainsIgnoreCase(FilterText!)) ||
|
||||||
|
(x.Citta != null && x.Citta.ContainsIgnoreCase(FilterText!)) ||
|
||||||
|
(x.Cap != null && x.Cap.ContainsIgnoreCase(FilterText!)) ||
|
||||||
|
(x.Provincia != null && x.Provincia.ContainsIgnoreCase(FilterText!))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
FilteredList = SteupDataService.PuntiVenditaList.FindAll(x =>
|
FilteredList = FilteredList.OrderBy(x => x.CodMdep).ToList();
|
||||||
(x.Indirizzo != null && x.Indirizzo.ContainsIgnoreCase(FilterText!)) ||
|
|
||||||
(x.Descrizione != null && x.Descrizione.ContainsIgnoreCase(FilterText!)) ||
|
|
||||||
(x.CodMdep != null && x.CodMdep.ContainsIgnoreCase(FilterText!)) ||
|
|
||||||
(x.Citta != null && x.Citta.ContainsIgnoreCase(FilterText!)) ||
|
|
||||||
(x.Cap != null && x.Cap.ContainsIgnoreCase(FilterText!)) ||
|
|
||||||
(x.Provincia != null && x.Provincia.ContainsIgnoreCase(FilterText!))
|
|
||||||
);
|
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ namespace SteUp.Shared.Core.Data.Contracts;
|
|||||||
public interface ISteupDataService
|
public interface ISteupDataService
|
||||||
{
|
{
|
||||||
Task Init();
|
Task Init();
|
||||||
|
Task<bool> CanOpenNewInspection();
|
||||||
void RegisterAppVersion();
|
void RegisterAppVersion();
|
||||||
|
Task CheckAndUpdateStatus();
|
||||||
|
|
||||||
List<PuntoVenditaDto> PuntiVenditaList { get; }
|
List<PuntoVenditaDto> PuntiVenditaList { get; }
|
||||||
InspectionPageState InspectionPageState { get; set; }
|
InspectionPageState InspectionPageState { get; set; }
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ using IntegryApiClient.Core.Domain.Abstraction.Contracts.Device;
|
|||||||
using SteUp.Shared.Core.Data.Contracts;
|
using SteUp.Shared.Core.Data.Contracts;
|
||||||
using SteUp.Shared.Core.Dto;
|
using SteUp.Shared.Core.Dto;
|
||||||
using SteUp.Shared.Core.Dto.PageState;
|
using SteUp.Shared.Core.Dto.PageState;
|
||||||
|
using SteUp.Shared.Core.Enum;
|
||||||
using SteUp.Shared.Core.Helpers;
|
using SteUp.Shared.Core.Helpers;
|
||||||
using SteUp.Shared.Core.Interface.IntegryApi;
|
using SteUp.Shared.Core.Interface.IntegryApi;
|
||||||
using SteUp.Shared.Core.Interface.LocalDb;
|
using SteUp.Shared.Core.Interface.LocalDb;
|
||||||
using SteUp.Shared.Core.Interface.System;
|
using SteUp.Shared.Core.Interface.System;
|
||||||
using SteUp.Shared.Core.Interface.System.Network;
|
|
||||||
|
|
||||||
namespace SteUp.Shared.Core.Data;
|
namespace SteUp.Shared.Core.Data;
|
||||||
|
|
||||||
@@ -17,6 +17,7 @@ public class SteupDataService(
|
|||||||
IDeviceService deviceService,
|
IDeviceService deviceService,
|
||||||
IGenericSystemService genericSystemService,
|
IGenericSystemService genericSystemService,
|
||||||
IIspezioniService ispezioniService,
|
IIspezioniService ispezioniService,
|
||||||
|
IFileManager fileManager,
|
||||||
IDbInitializer dbInitializer) : ISteupDataService
|
IDbInitializer dbInitializer) : ISteupDataService
|
||||||
{
|
{
|
||||||
public async Task Init()
|
public async Task Init()
|
||||||
@@ -24,6 +25,7 @@ public class SteupDataService(
|
|||||||
await dbInitializer.InitializeAsync();
|
await dbInitializer.InitializeAsync();
|
||||||
await LoadDataAsync();
|
await LoadDataAsync();
|
||||||
await CheckAndUpdateStatus();
|
await CheckAndUpdateStatus();
|
||||||
|
await CleanOldClosedInspection();
|
||||||
RegisterAppVersion();
|
RegisterAppVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,9 +36,24 @@ public class SteupDataService(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task CheckAndUpdateStatus()
|
private async Task CleanOldClosedInspection()
|
||||||
{
|
{
|
||||||
var ispezioni = await ispezioniService.GetAllIspezioniWithSchedeAsync();
|
var ispezioni = (await ispezioniService.GetAllIspezioniWithSchedeAsync(userSession.User.Username))
|
||||||
|
.Where(x =>
|
||||||
|
x.Stato == StatusEnum.Completata &&
|
||||||
|
x.Data < DateTime.Now.AddDays(-60)
|
||||||
|
).ToList();
|
||||||
|
|
||||||
|
foreach (var ispezione in ispezioni)
|
||||||
|
{
|
||||||
|
fileManager.RemoveInspection(ispezione);
|
||||||
|
await ispezioniService.DeleteIspezioneAsync(ispezione.CodMdep, ispezione.Data, ispezione.Rilevatore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task CheckAndUpdateStatus()
|
||||||
|
{
|
||||||
|
var ispezioni = await ispezioniService.GetAllIspezioniWithSchedeAsync(userSession.User.Username);
|
||||||
var listActivityId = ispezioni
|
var listActivityId = ispezioni
|
||||||
.Where(x => x.ActivityId != null)
|
.Where(x => x.ActivityId != null)
|
||||||
.Select(x => x.ActivityId!)
|
.Select(x => x.ActivityId!)
|
||||||
@@ -76,6 +93,20 @@ public class SteupDataService(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> CanOpenNewInspection()
|
||||||
|
{
|
||||||
|
var completedInspection = await ispezioniService.GetAllIspezioni(userSession.User.Username);
|
||||||
|
|
||||||
|
if (completedInspection.IsNullOrEmpty()) return true;
|
||||||
|
|
||||||
|
//Controllo se sono presenti attività più vecchie di 20 giorni non chiuse
|
||||||
|
//Se presenti non si possono aprire nuove ispezioni
|
||||||
|
return !completedInspection.Any(x =>
|
||||||
|
x.Stato != StatusEnum.Completata &&
|
||||||
|
x.Data < DateTime.Now.AddDays(-20)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task LoadDataAsync()
|
private async Task LoadDataAsync()
|
||||||
{
|
{
|
||||||
if (!await userSession.IsLoggedIn()) return;
|
if (!await userSession.IsLoggedIn()) return;
|
||||||
|
|||||||
33
SteUp.Shared/Core/Dto/SendEmailDto.cs
Normal file
33
SteUp.Shared/Core/Dto/SendEmailDto.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace SteUp.Shared.Core.Dto;
|
||||||
|
|
||||||
|
public class SendEmailDto
|
||||||
|
{
|
||||||
|
[JsonPropertyName("from")]
|
||||||
|
public string? From { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("fromName")]
|
||||||
|
public string? FromName { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("to")]
|
||||||
|
public string? To { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("subject")]
|
||||||
|
public string? Subject { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("msgText")]
|
||||||
|
public string? MsgText { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("html")]
|
||||||
|
public bool IsHtml { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("attachments")]
|
||||||
|
public List<AttachmentsDto>? Attachments { get; set; }
|
||||||
|
|
||||||
|
public class AttachmentsDto
|
||||||
|
{
|
||||||
|
public string FileName { get; set; } = string.Empty;
|
||||||
|
public byte[] FileContent { get; set; } = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,129 +6,155 @@ using SteUp.Shared.Core.Entities;
|
|||||||
|
|
||||||
namespace SteUp.Shared.Core.Helpers;
|
namespace SteUp.Shared.Core.Helpers;
|
||||||
|
|
||||||
public abstract class ModalHelper
|
public static class ModalHelper
|
||||||
{
|
{
|
||||||
public static async Task<DialogResult?> OpenSelectShop(IDialogService dialog)
|
extension(IDialogService dialog)
|
||||||
{
|
{
|
||||||
var modal = await dialog.ShowAsync<ModalSelectShop>(
|
public async Task<DialogResult?> OpenSelectShop()
|
||||||
"ModalSelectShop",
|
{
|
||||||
new DialogParameters(),
|
var modal = await dialog.ShowAsync<ModalSelectShop>(
|
||||||
new DialogOptions
|
"ModalSelectShop",
|
||||||
{
|
new DialogParameters(),
|
||||||
FullScreen = false,
|
new DialogOptions
|
||||||
CloseButton = false,
|
{
|
||||||
NoHeader = true,
|
FullScreen = false,
|
||||||
BackdropClick = true
|
CloseButton = false,
|
||||||
}
|
NoHeader = true,
|
||||||
);
|
BackdropClick = true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return await modal.Result;
|
return await modal.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<DialogResult?> OpenFormScheda(IDialogService dialog, string codMdep, DateTime data,
|
public async Task<DialogResult?> OpenFormScheda(string codMdep, DateTime data,
|
||||||
bool isNew = false, Scheda? scheda = null)
|
bool isNew = false, Scheda? scheda = null, bool readOnly = false)
|
||||||
{
|
{
|
||||||
scheda = isNew && scheda == null ? new Scheda() : scheda;
|
scheda = isNew && scheda == null ? new Scheda() : scheda;
|
||||||
|
|
||||||
var modal = await dialog.ShowAsync<ModalFormScheda>(
|
var modal = await dialog.ShowAsync<ModalFormScheda>(
|
||||||
"ModalFormScheda",
|
"ModalFormScheda",
|
||||||
new DialogParameters<ModalFormScheda>
|
new DialogParameters<ModalFormScheda>
|
||||||
{
|
{
|
||||||
{ x => x.CodMdep, codMdep },
|
{ x => x.CodMdep, codMdep },
|
||||||
{ x => x.Data, data },
|
{ x => x.Data, data },
|
||||||
{ x => x.IsNew, isNew },
|
{ x => x.IsNew, isNew },
|
||||||
{ x => x.Scheda, scheda }
|
{ x => x.ReadOnly, readOnly },
|
||||||
},
|
{ x => x.Scheda, scheda }
|
||||||
new DialogOptions
|
},
|
||||||
{
|
new DialogOptions
|
||||||
FullScreen = true,
|
{
|
||||||
CloseButton = false,
|
FullScreen = true,
|
||||||
NoHeader = true
|
CloseButton = false,
|
||||||
}
|
NoHeader = true
|
||||||
);
|
}
|
||||||
|
);
|
||||||
|
|
||||||
return await modal.Result;
|
return await modal.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<DialogResult?> OpenAddAttached(IDialogService dialog)
|
public async Task<DialogResult?> OpenAddAttached()
|
||||||
{
|
{
|
||||||
var modal = await dialog.ShowAsync<ModalAddAttached>(
|
var modal = await dialog.ShowAsync<ModalAddAttached>(
|
||||||
"Add attached",
|
"Add attached",
|
||||||
new DialogParameters(),
|
new DialogParameters(),
|
||||||
new DialogOptions
|
new DialogOptions
|
||||||
{
|
{
|
||||||
FullScreen = false,
|
FullScreen = false,
|
||||||
CloseButton = false,
|
CloseButton = false,
|
||||||
NoHeader = true,
|
NoHeader = true,
|
||||||
BackdropClick = false
|
BackdropClick = false
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return await modal.Result;
|
return await modal.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<DialogResult?> OpenSuggestActivityDescription(IDialogService dialog,
|
public async Task<DialogResult?> OpenSuggestActivityDescription(List<StbActivityTyperDto>? activityTypers)
|
||||||
List<StbActivityTyperDto>? activityTypers)
|
{
|
||||||
{
|
var modal = await dialog.ShowAsync<ModalSuggestDescription>(
|
||||||
var modal = await dialog.ShowAsync<ModalSuggestDescription>(
|
"Suggest activity description",
|
||||||
"Suggest activity description",
|
new DialogParameters<ModalSuggestDescription>
|
||||||
new DialogParameters<ModalSuggestDescription>
|
{
|
||||||
{
|
{ x => x.ActivityTypers, activityTypers }
|
||||||
{ x => x.ActivityTypers, activityTypers }
|
},
|
||||||
},
|
new DialogOptions
|
||||||
new DialogOptions
|
{
|
||||||
{
|
FullScreen = false,
|
||||||
FullScreen = false,
|
CloseButton = false,
|
||||||
CloseButton = false,
|
NoHeader = true,
|
||||||
NoHeader = true,
|
BackdropClick = true
|
||||||
BackdropClick = true
|
}
|
||||||
}
|
);
|
||||||
);
|
|
||||||
|
|
||||||
return await modal.Result;
|
return await modal.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<DialogResult?> OpenSelectArt(IDialogService dialog, List<ArticoliInGrigliaDto>? articoli)
|
public async Task<DialogResult?> OpenSelectArt(List<ArticoliInGrigliaDto>? articoli)
|
||||||
{
|
{
|
||||||
var modal = await dialog.ShowAsync<ModalSelectArt>(
|
var modal = await dialog.ShowAsync<ModalSelectArt>(
|
||||||
"ModalSelectArt",
|
"ModalSelectArt",
|
||||||
new DialogParameters<ModalSelectArt>
|
new DialogParameters<ModalSelectArt>
|
||||||
{
|
{
|
||||||
{ x => x.Articoli, articoli }
|
{ x => x.Articoli, articoli }
|
||||||
},
|
},
|
||||||
new DialogOptions
|
new DialogOptions
|
||||||
{
|
{
|
||||||
FullScreen = false,
|
FullScreen = false,
|
||||||
CloseButton = false,
|
CloseButton = false,
|
||||||
NoHeader = true,
|
NoHeader = true,
|
||||||
BackdropClick = true,
|
BackdropClick = true,
|
||||||
FullWidth = true,
|
FullWidth = true,
|
||||||
MaxWidth = MaxWidth.ExtraLarge
|
MaxWidth = MaxWidth.ExtraLarge
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return await modal.Result;
|
return await modal.Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task ShowError(IDialogService dialog, string message)
|
public async Task ShowError(string message)
|
||||||
{
|
{
|
||||||
var modal = await dialog.ShowAsync<ModalError>(
|
var modal = await dialog.ShowAsync<ModalError>(
|
||||||
"ModalError",
|
"ModalError",
|
||||||
new DialogParameters<ModalError>
|
new DialogParameters<ModalError>
|
||||||
{
|
{
|
||||||
{ x => x.ErrorMessage, message }
|
{ x => x.ErrorMessage, message }
|
||||||
},
|
},
|
||||||
new DialogOptions
|
new DialogOptions
|
||||||
{
|
{
|
||||||
FullScreen = false,
|
FullScreen = false,
|
||||||
CloseButton = false,
|
CloseButton = false,
|
||||||
NoHeader = true,
|
NoHeader = true,
|
||||||
BackdropClick = true,
|
BackdropClick = true,
|
||||||
FullWidth = true,
|
FullWidth = true,
|
||||||
MaxWidth = MaxWidth.ExtraLarge
|
MaxWidth = MaxWidth.ExtraLarge
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
await modal.Result;
|
await modal.Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ShowWarning(string message)
|
||||||
|
{
|
||||||
|
var modal = await dialog.ShowAsync<ModalError>(
|
||||||
|
"ModalError",
|
||||||
|
new DialogParameters<ModalError>
|
||||||
|
{
|
||||||
|
{ x => x.ErrorMessage, message },
|
||||||
|
{ x => x.IsWarning, true }
|
||||||
|
},
|
||||||
|
new DialogOptions
|
||||||
|
{
|
||||||
|
FullScreen = false,
|
||||||
|
CloseButton = false,
|
||||||
|
NoHeader = true,
|
||||||
|
BackdropClick = true,
|
||||||
|
FullWidth = true,
|
||||||
|
MaxWidth = MaxWidth.ExtraLarge
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
await modal.Result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,4 +7,6 @@ public interface IIntegryApiService
|
|||||||
Task<bool> SystemOk();
|
Task<bool> SystemOk();
|
||||||
|
|
||||||
Task<List<StbActivityTyperDto>?> SuggestActivityDescription(string activityTypeId);
|
Task<List<StbActivityTyperDto>?> SuggestActivityDescription(string activityTypeId);
|
||||||
|
|
||||||
|
Task SendEmail(SendEmailDto sendEmail);
|
||||||
}
|
}
|
||||||
@@ -17,4 +17,6 @@ public interface IIntegrySteupService
|
|||||||
Task<SaveSchedaResponseDto?> SaveMultipleSchede(List<SaveRequestDto> request);
|
Task<SaveSchedaResponseDto?> SaveMultipleSchede(List<SaveRequestDto> request);
|
||||||
Task CompleteInspection(string activityId);
|
Task CompleteInspection(string activityId);
|
||||||
Task UploadFile(string activityId, byte[] file, string fileName);
|
Task UploadFile(string activityId, byte[] file, string fileName);
|
||||||
|
|
||||||
|
Task DeleteScheda(string activityId);
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using SteUp.Shared.Core.Entities;
|
using System.Linq.Expressions;
|
||||||
|
using SteUp.Shared.Core.Entities;
|
||||||
using SteUp.Shared.Core.Enum;
|
using SteUp.Shared.Core.Enum;
|
||||||
|
|
||||||
namespace SteUp.Shared.Core.Interface.LocalDb;
|
namespace SteUp.Shared.Core.Interface.LocalDb;
|
||||||
@@ -7,7 +8,8 @@ public interface IIspezioniService
|
|||||||
{
|
{
|
||||||
// ISPEZIONI
|
// ISPEZIONI
|
||||||
Task<Ispezione?> GetIspezioneAsync(string codMdep, DateTime data, string rilevatore);
|
Task<Ispezione?> GetIspezioneAsync(string codMdep, DateTime data, string rilevatore);
|
||||||
Task<List<Ispezione>> GetAllIspezioniWithSchedeAsync();
|
Task<List<Ispezione>> GetAllIspezioni(string rilevatore);
|
||||||
|
Task<List<Ispezione>> GetAllIspezioniWithSchedeAsync(string rilevatore);
|
||||||
Task AddIspezioneAsync(Ispezione ispezione);
|
Task AddIspezioneAsync(Ispezione ispezione);
|
||||||
Task<Ispezione> GetOrCreateIspezioneAsync(string codMdep, DateTime data, string rilevatore);
|
Task<Ispezione> GetOrCreateIspezioneAsync(string codMdep, DateTime data, string rilevatore);
|
||||||
Task<bool> UpdateIspezioneAsync(Ispezione ispezione);
|
Task<bool> UpdateIspezioneAsync(Ispezione ispezione);
|
||||||
@@ -22,6 +24,7 @@ public interface IIspezioniService
|
|||||||
Task<Scheda?> GetSchedaWithIspezioneAsync(int schedaId);
|
Task<Scheda?> GetSchedaWithIspezioneAsync(int schedaId);
|
||||||
Task<bool> UpdateSchedaAsync(Scheda scheda);
|
Task<bool> UpdateSchedaAsync(Scheda scheda);
|
||||||
Task<bool> UpdateActivityIdSchedaAsync(int schedaId, string? activityId);
|
Task<bool> UpdateActivityIdSchedaAsync(int schedaId, string? activityId);
|
||||||
|
Task<bool> UpdateFileListSchedaAsync(int schedaId, List<string>? imageNames);
|
||||||
Task<bool> DeleteSchedaAsync(int schedaId);
|
Task<bool> DeleteSchedaAsync(int schedaId);
|
||||||
Task<int> DeleteAllSchedeOfIspezioneAsync(string codMdep, DateTime data, string rilevatore);
|
Task<int> DeleteAllSchedeOfIspezioneAsync(string codMdep, DateTime data, string rilevatore);
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using SteUp.Shared.Core.Dto;
|
using SteUp.Shared.Core.Dto;
|
||||||
using SteUp.Shared.Core.Entities;
|
|
||||||
|
|
||||||
namespace SteUp.Shared.Core.Interface.System;
|
namespace SteUp.Shared.Core.Interface.System;
|
||||||
|
|
||||||
@@ -7,22 +6,4 @@ public interface IAttachedService
|
|||||||
{
|
{
|
||||||
Task<AttachedDto?> SelectImageFromCamera();
|
Task<AttachedDto?> SelectImageFromCamera();
|
||||||
Task<List<AttachedDto>?> SelectImageFromGallery();
|
Task<List<AttachedDto>?> SelectImageFromGallery();
|
||||||
|
|
||||||
Task<List<AttachedDto>?> GetInspectionFiles(Ispezione ispezione, List<string> fileNameFilter,
|
|
||||||
bool includeToUpload = true, CancellationToken ct = default);
|
|
||||||
|
|
||||||
Task<string?> SaveInspectionFile(Ispezione ispezione, byte[] file, string fileName, CancellationToken ct = default);
|
|
||||||
|
|
||||||
bool RemoveInspectionFile(Ispezione ispezione, string fileName, bool removeAlsoFromFinal = true,
|
|
||||||
bool removeAlsoFromToUpload = true);
|
|
||||||
|
|
||||||
Task<bool> MoveInspectionFileFromToUploadToFinal(Ispezione ispezione, string fileName, bool overwrite = true,
|
|
||||||
CancellationToken ct = default);
|
|
||||||
|
|
||||||
Task<string> SaveToTempStorage(Stream file, string fileName, CancellationToken ct = default);
|
|
||||||
Task CleanTempStorageAsync(CancellationToken ct = default);
|
|
||||||
Task OpenFile(string fileName, string filePath);
|
|
||||||
|
|
||||||
Task<(string originalUrl, string thumbUrl)> SaveAndCreateThumbAsync(byte[] bytes, string fileName,
|
|
||||||
CancellationToken ct = default);
|
|
||||||
}
|
}
|
||||||
30
SteUp.Shared/Core/Interface/System/IFileManager.cs
Normal file
30
SteUp.Shared/Core/Interface/System/IFileManager.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using SteUp.Shared.Core.Dto;
|
||||||
|
using SteUp.Shared.Core.Entities;
|
||||||
|
|
||||||
|
namespace SteUp.Shared.Core.Interface.System;
|
||||||
|
|
||||||
|
public interface IFileManager
|
||||||
|
{
|
||||||
|
Task<List<AttachedDto>?> GetInspectionFiles(Ispezione ispezione, List<string> fileNameFilter,
|
||||||
|
bool includeToUpload = true, CancellationToken ct = default);
|
||||||
|
|
||||||
|
Task<string?> SaveInspectionFile(Ispezione ispezione, byte[] file, string fileName, CancellationToken ct = default);
|
||||||
|
|
||||||
|
string GetFileToUploadDir(Ispezione ispezione, string fileName);
|
||||||
|
|
||||||
|
bool RemoveInspection(Ispezione ispezione, bool removeAlsoFromFinal = true, bool removeAlsoFromToUpload = true);
|
||||||
|
bool RemoveInspectionFile(Ispezione ispezione, string fileName, bool removeAlsoFromFinal = true,
|
||||||
|
bool removeAlsoFromToUpload = true);
|
||||||
|
|
||||||
|
Task<string?> MoveInspectionFileFromToUploadToFinal(Ispezione ispezione, string fileName, bool overwrite = true,
|
||||||
|
CancellationToken ct = default);
|
||||||
|
|
||||||
|
Task<string> SaveToTempStorage(Stream file, string fileName, CancellationToken ct = default);
|
||||||
|
Task CleanTempStorageAsync(CancellationToken ct = default);
|
||||||
|
Task OpenFile(string fileName, string filePath);
|
||||||
|
|
||||||
|
Task<(string originalUrl, string thumbUrl)> SaveAndCreateThumbAsync(byte[] bytes, string fileName,
|
||||||
|
CancellationToken ct = default);
|
||||||
|
|
||||||
|
List<SendEmailDto.AttachmentsDto> GetFileForExport();
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using IntegryApiClient.Core.Domain.Abstraction.Contracts.Account;
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
using IntegryApiClient.Core.Domain.RestClient.Contacts;
|
using IntegryApiClient.Core.Domain.RestClient.Contacts;
|
||||||
using MudBlazor;
|
using Microsoft.Extensions.Logging;
|
||||||
using SteUp.Shared.Core.Dto;
|
using SteUp.Shared.Core.Dto;
|
||||||
using SteUp.Shared.Core.Interface.IntegryApi;
|
using SteUp.Shared.Core.Interface.IntegryApi;
|
||||||
|
|
||||||
@@ -8,7 +10,7 @@ namespace SteUp.Shared.Core.Services;
|
|||||||
|
|
||||||
public class IntegryApiService(
|
public class IntegryApiService(
|
||||||
IIntegryApiRestClient integryApiRestClient,
|
IIntegryApiRestClient integryApiRestClient,
|
||||||
IUserSession userSession) : IIntegryApiService
|
ILogger<IntegryApiService> logger) : IIntegryApiService
|
||||||
{
|
{
|
||||||
public async Task<bool> SystemOk()
|
public async Task<bool> SystemOk()
|
||||||
{
|
{
|
||||||
@@ -19,6 +21,7 @@ public class IntegryApiService(
|
|||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
logger.LogError(e, e.Message);
|
||||||
Console.WriteLine(e.Message);
|
Console.WriteLine(e.Message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -31,4 +34,44 @@ public class IntegryApiService(
|
|||||||
{ "activityType", activityTypeId }
|
{ "activityType", activityTypeId }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
public async Task SendEmail(SendEmailDto sendEmail)
|
||||||
|
{
|
||||||
|
var content = new MultipartFormDataContent();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (sendEmail.Attachments != null)
|
||||||
|
{
|
||||||
|
foreach (var a in sendEmail.Attachments)
|
||||||
|
{
|
||||||
|
var fileContent = new ByteArrayContent(a.FileContent);
|
||||||
|
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||||
|
content.Add(fileContent, "allegati", a.FileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendEmail.Attachments = null;
|
||||||
|
content.Add(
|
||||||
|
new StringContent(
|
||||||
|
JsonSerializer.Serialize(sendEmail),
|
||||||
|
Encoding.UTF8,
|
||||||
|
"application/json"
|
||||||
|
),
|
||||||
|
"request"
|
||||||
|
);
|
||||||
|
|
||||||
|
await integryApiRestClient.AuthorizedPost<object>("sendEmailNew", content);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
logger.LogError(e, e.Message);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
content.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -48,23 +48,34 @@ public class IntegrySteupService(IIntegryApiRestClient integryApiRestClient) : I
|
|||||||
public Task CompleteInspection(string activityId) =>
|
public Task CompleteInspection(string activityId) =>
|
||||||
integryApiRestClient.AuthorizedPost<object>(
|
integryApiRestClient.AuthorizedPost<object>(
|
||||||
$"{BaseRequest}/complete",
|
$"{BaseRequest}/complete",
|
||||||
|
new object(),
|
||||||
|
new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "activityId", activityId }
|
||||||
|
}!
|
||||||
|
);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public async Task UploadFile(string activityId, byte[] file, string fileName)
|
||||||
|
{
|
||||||
|
var queryParams = new Dictionary<string, object> { { "activityId", activityId } };
|
||||||
|
|
||||||
|
var content = new MultipartFormDataContent();
|
||||||
|
var fileContent = new ByteArrayContent(file);
|
||||||
|
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
||||||
|
content.Add(fileContent, "file", fileName);
|
||||||
|
|
||||||
|
await integryApiRestClient.Post<object>($"{BaseRequest}/uploadAttachment", content, queryParams!);
|
||||||
|
content.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteScheda(string activityId) =>
|
||||||
|
integryApiRestClient.AuthorizedGet<object>(
|
||||||
|
$"{BaseRequest}/deleteScheda",
|
||||||
new Dictionary<string, object>
|
new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "activityId", activityId }
|
{ "activityId", activityId }
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public Task UploadFile(string activityId, byte[] file, string fileName)
|
|
||||||
{
|
|
||||||
var queryParams = new Dictionary<string, object> { { "activityId", activityId } };
|
|
||||||
|
|
||||||
using var content = new MultipartFormDataContent();
|
|
||||||
var fileContent = new ByteArrayContent(file);
|
|
||||||
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
|
|
||||||
content.Add(fileContent, "file", fileName);
|
|
||||||
|
|
||||||
return integryApiRestClient.Post<object>($"{BaseRequest}/uploadAttachment", content, queryParams!);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user