Skip to content

Commit

Permalink
feat: 587
Browse files Browse the repository at this point in the history
Merged PR 182: Rel righe asincrono

Related work items: #587
  • Loading branch information
mg-dgsspa committed Mar 4, 2025
1 parent 5696400 commit 6ef29e7
Show file tree
Hide file tree
Showing 14 changed files with 341 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ public interface IPortaleFattureOptions
public Synapse? Synapse { get; set; }
public SelfCareOnBoarding? SelfCareOnBoarding { get; set; }
public StoragePagoPAFinancial? StoragePagoPAFinancial { get; set; }
public SupportAPIService? SupportAPIService { get; set; }
public SupportAPIService? SupportAPIService { get; set; }
public StorageREL? StorageREL { get; set; }
}
11 changes: 10 additions & 1 deletion src/Core/PortaleFatture.BE.Core/Common/PortaleFattureOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,16 @@ public sealed class PortaleFattureOptions : IPortaleFattureOptions
public Synapse? Synapse { get; set; }
public StoragePagoPAFinancial? StoragePagoPAFinancial { get; set; }
public SelfCareOnBoarding? SelfCareOnBoarding { get; set; }
public SupportAPIService? SupportAPIService { get; set; }
public SupportAPIService? SupportAPIService { get; set; }
public StorageREL? StorageREL { get; set; }
}

public class StorageREL()
{
public string? StorageRELAccountName { get; set; }
public string? StorageRELAccountKey { get; set; }
public string? StorageRELBlobContainerName { get; set; }
public string? StorageRELCustomDns { get; set; }
}

public class SupportAPIService()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace PortaleFatture.BE.Infrastructure.Common.SEND.DatiRel.Services;
public interface IRelRigheStorageService
{
string? GetBlobName(string sidtestata, string nomeEnte, string? extension = ".csv");
string? GetSASToken(string sidtestata, string nomeEnte);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Azure.Storage.Sas;
using Azure.Storage;
using PortaleFatture.BE.Core.Entities.SEND.DatiRel;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using PortaleFatture.BE.Core.Common;
using PortaleFatture.BE.Core.Resources;
using PortaleFatture.BE.Infrastructure.Gateway.Storage;

namespace PortaleFatture.BE.Infrastructure.Common.SEND.DatiRel.Services;

public class RelRigheStorageService(IPortaleFattureOptions options,
IStringLocalizer<Localization> localizer,
ILogger<RelStorageService> logger) : IRelRigheStorageService
{
private readonly IStringLocalizer<Localization> _localizer = localizer;
private readonly ILogger<RelStorageService> _logger = logger;
private readonly IPortaleFattureOptions _options = options;
private string _accountName { get; set; } = options.StorageREL!.StorageRELAccountName!;
private string _accountKey { get; set; } = options.StorageREL!.StorageRELAccountKey!;
private string _blobContainerName { get; set; } = options.StorageREL!.StorageRELBlobContainerName!;
private string _customDNS { get; set; } = options.StorageREL!.StorageRELCustomDns!;

public string? GetBlobName(string sidtestata, string nomeEnte, string? extension = ".csv")
{
var idTestata = RelTestataKey.Deserialize(sidtestata);
return $"{idTestata.Anno}/{idTestata.Mese}/{idTestata.TipologiaFattura}/{idTestata.IdEnte}/{idTestata.IdContratto}/Rel_Report di dettaglio_{nomeEnte}_{idTestata.Mese}_{idTestata.Anno}{extension}";
}

public string? GetSASToken(string sidtestata, string nomeEnte)
{
var blobName = GetBlobName(sidtestata, nomeEnte);
var sasToken = GenerateBlobSasToken(_accountName, _accountKey, _blobContainerName, blobName);
return $"{_customDNS}/{_blobContainerName}/{blobName}?{sasToken}";
}

static string GenerateBlobSasToken(string accountName, string accountKey, string containerName, string? blobName)
{
var credential = new StorageSharedKeyCredential(accountName, accountKey);

var sasBuilder = new BlobSasBuilder()
{
BlobContainerName = containerName,
BlobName = blobName,
Resource = "b", // "b" for blob-level SAS
ExpiresOn = DateTimeOffset.UtcNow.AddHours(1),
StartsOn = DateTimeOffset.UtcNow.AddHours(-1)
};

sasBuilder.SetPermissions(BlobSasPermissions.Read);

return sasBuilder.ToSasQueryParameters(credential).ToString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using PortaleFatture.BE.Infrastructure.Common.Persistence;
using PortaleFatture.BE.Infrastructure.Common.Persistence.Schemas;
using PortaleFatture.BE.Infrastructure.Common.SEND;
using PortaleFatture.BE.Infrastructure.Common.SEND.DatiRel.Services;
using PortaleFatture.BE.Infrastructure.Common.SEND.Documenti;
using PortaleFatture.BE.Infrastructure.Common.SEND.Fatture.Dto;
using PortaleFatture.BE.Infrastructure.Common.SEND.Fatture.Service;
Expand Down Expand Up @@ -158,9 +159,10 @@ static IAsyncPolicy<HttpResponseMessage> ExponentialRetryPolicy()
// storages
services.AddSingleton<IRelStorageService, RelStorageService>();
services.AddSingleton<IDocumentStorageService, DocumentStorageService>();
services.AddSingleton<IDocumentStorageSASService, DocumentStorageSASService>();

services.AddSingleton<IDocumentStorageSASService, DocumentStorageSASService>();

// rel righe storage
services.AddSingleton<IRelRigheStorageService, RelRigheStorageService>();


services.AddSingleton<IManualiStorageSASService, ManualiStorageSASService>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public static async Task<PortaleFattureOptions> VaultClientSettings(this Portale
model.StoragePagoPAFinancial??= new();
model.SelfCareOnBoarding??= new();
model.SupportAPIService??= new();
model.StorageREL ??= new();

var selfCareUri = Environment.GetEnvironmentVariable("SELF_CARE_URI") ??
throw new ConfigurationException("Please specify a SELF_CARE_URI!");
Expand Down Expand Up @@ -116,6 +117,20 @@ public static async Task<PortaleFattureOptions> VaultClientSettings(this Portale
var supportAPIServiceAuthToken = Environment.GetEnvironmentVariable("SUPPORTAPISERVICE_AUTHTOKEN") ??
throw new ConfigurationException("Please specify SUPPORTAPISERVICE_AUTHTOKEN!");

// REL storage righe
var storageRELAccountName = Environment.GetEnvironmentVariable("StorageRELAccountName") ??
throw new ConfigurationException("Please specify StorageRELAccountName!");

var storageRELAccountKey = Environment.GetEnvironmentVariable("StorageRELAccountKey") ??
throw new ConfigurationException("Please specify StorageRELAccountKey!");

var storageRELBlobContainerName = Environment.GetEnvironmentVariable("StorageRELBlobContainerName") ??
throw new ConfigurationException("Please specify StorageRELBlobContainerName!");

var storageRELCustomDns = Environment.GetEnvironmentVariable("StorageRELCustomDns") ??
throw new ConfigurationException("Please specify StorageRELCustomDns!");


model.ConnectionString = connectionString; //await model.ConnectionString.Mapper();

model.JWT.ValidAudience = validAudience;
Expand Down Expand Up @@ -159,6 +174,11 @@ public static async Task<PortaleFattureOptions> VaultClientSettings(this Portale
model.SupportAPIService.RecipientCodeUri = supportAPIServiceRecipientCodeUri;
model.SupportAPIService.AuthToken = supportAPIServiceAuthToken;

model.StorageREL.StorageRELAccountName = storageRELAccountName;
model.StorageREL.StorageRELAccountKey = storageRELAccountKey;
model.StorageREL.StorageRELBlobContainerName = storageRELBlobContainerName;
model.StorageREL.StorageRELCustomDns = storageRELCustomDns;

return model;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
using MediatR;
using System.Net.Http.Headers;
using DocumentFormat.OpenXml.Bibliography;
using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using PortaleFatture.BE.Api.Infrastructure;
using PortaleFatture.BE.Api.Infrastructure.Documenti;
using PortaleFatture.BE.Api.Modules.pagoPA.FinancialReports.Extensions;
using PortaleFatture.BE.Api.Modules.SEND.DatiFatturazioni.Payload.Request;
using PortaleFatture.BE.Api.Modules.SEND.DatiRel.Extensions;
using PortaleFatture.BE.Api.Modules.SEND.DatiRel.Payload.Request;
Expand All @@ -23,6 +26,7 @@
using PortaleFatture.BE.Infrastructure.Common.SEND.DatiRel.Dto;
using PortaleFatture.BE.Infrastructure.Common.SEND.DatiRel.Extensions;
using PortaleFatture.BE.Infrastructure.Common.SEND.DatiRel.Queries;
using PortaleFatture.BE.Infrastructure.Common.SEND.DatiRel.Services;
using PortaleFatture.BE.Infrastructure.Common.SEND.Documenti;
using PortaleFatture.BE.Infrastructure.Common.SEND.Documenti.Common;
using PortaleFatture.BE.Infrastructure.Common.SEND.SelfCare.Queries;
Expand All @@ -45,14 +49,14 @@ private async Task<Results<Ok<IEnumerable<string>>, NotFound>> GetAnniRelAsync(
HttpContext context,
[FromServices] IStringLocalizer<Localization> localizer,
[FromServices] IMediator handler)
{
var authInfo = context.GetAuthInfo();
{
var authInfo = context.GetAuthInfo();

var anni = await handler.Send(new RelAnniQuery(authInfo));
if (anni.IsNullNotAny())
return NotFound();
return Ok(anni);
}
var anni = await handler.Send(new RelAnniQuery(authInfo));
if (anni.IsNullNotAny())
return NotFound();
return Ok(anni);
}

[Authorize(Roles = $"{Ruolo.OPERATOR}, {Ruolo.ADMIN}", Policy = Module.PagoPAPolicy)]
[EnableCors(CORSLabel)]
Expand Down Expand Up @@ -91,25 +95,25 @@ private async Task<Results<Ok<IEnumerable<RelMeseResponse>>, NotFound>> PostMesi
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status500InternalServerError)]
private async Task<IResult> GetRelNonFatturateExcelAsync(
HttpContext context,
HttpContext context,
[FromServices] IStringLocalizer<Localization> localizer,
[FromServices] IMediator handler)
{
var authInfo = context.GetAuthInfo();
var rel = await handler.Send(new RelNonFatturateQuery(authInfo));
if (rel == null || !rel!.Any())
return NotFound();
var mime = "application/vnd.ms-excel";
var filename = $"{Guid.NewGuid()}.xlsx";
{
var authInfo = context.GetAuthInfo();
var rel = await handler.Send(new RelNonFatturateQuery(authInfo));
if (rel == null || !rel!.Any())
return NotFound();
var mime = "application/vnd.ms-excel";
var filename = $"{Guid.NewGuid()}.xlsx";

var dataSet = rel.FillOneSheetv2();
var content = dataSet.ToExcel();
var result = new DisposableStreamResult(content, mime)
{
FileDownloadName = filename
};
return Results.Stream(result.FileStream, result.ContentType, result.FileDownloadName);
}
var dataSet = rel.FillOneSheetv2();
var content = dataSet.ToExcel();
var result = new DisposableStreamResult(content, mime)
{
FileDownloadName = filename
};
return Results.Stream(result.FileStream, result.ContentType, result.FileDownloadName);
}

[Authorize(Roles = $"{Ruolo.OPERATOR}, {Ruolo.ADMIN}", Policy = Module.PagoPAPolicy)]
[EnableCors(CORSLabel)]
Expand All @@ -122,14 +126,14 @@ private async Task<Results<Ok<IEnumerable<string>>, NotFound>> PostTipologiaFatt
[FromBody] RelTipologiaFatturaPagoPARequest? request,
[FromServices] IMediator handler,
[FromServices] IStringLocalizer<Localization> localizer)
{
var authInfo = context.GetAuthInfo();
{
var authInfo = context.GetAuthInfo();

var tipologie = await handler.Send(request!.Map(authInfo));
if (tipologie == null || tipologie.Count() == 0)
return NotFound();
return Ok(tipologie);
}
var tipologie = await handler.Send(request!.Map(authInfo));
if (tipologie == null || tipologie.Count() == 0)
return NotFound();
return Ok(tipologie);
}


[Authorize(Roles = $"{Ruolo.OPERATOR}, {Ruolo.ADMIN}", Policy = Module.PagoPAPolicy)]
Expand All @@ -152,7 +156,7 @@ private async Task<IResult> GetDownloadPagoPAAsync(
IdTestata = id
};
var rel = await handler.Send(request.Map(authInfo));
if (rel == null
if (rel == null
|| rel.TipologiaFattura!.ToLower().Contains("var")
|| rel.TipologiaFattura!.ToLower().Contains("semestrale")
|| rel.TipologiaFattura!.ToLower().Contains("annuale"))
Expand Down Expand Up @@ -386,25 +390,23 @@ private async Task<IResult> GetPagoPARelRigheDocumentAsync(
[FromRoute] string? id,
[FromServices] IStringLocalizer<Localization> localizer,
[FromServices] IMediator handler,
[FromServices] IRelRigheStorageService storageService,
[FromQuery] bool? binary = null)
{
var authInfo = context.GetAuthInfo();
var idEnte = id!.Split("_")[0];
authInfo.IdEnte = idEnte;
var request = new RelRigheByIdRequest()
{
IdTestata = id
};

var rels = await handler.Send(request.Map(authInfo));
if (rels.IsNullNotAny())
var ente = await handler.Send(new EnteQueryGetById(authInfo) { });
if (ente == null)
return NotFound();

var stream = await rels!.ToStream<RigheRelDto, RigheRelDtoPagoPAMap>();
var filename = $"{Guid.NewGuid()}.csv";
var mimeCsv = "text/csv";
stream.Position = 0;
return Results.Stream(stream, mimeCsv, filename);
var url = storageService.GetSASToken(id, ente.Descrizione!);
url = url!.FileExistsAsync();
if(string.IsNullOrEmpty(url))
return NotFound();

return Ok(url);
}

[Authorize(Roles = $"{Ruolo.OPERATOR}, {Ruolo.ADMIN}", Policy = Module.PagoPAPolicy)]
Expand Down Expand Up @@ -466,11 +468,11 @@ private async Task<Results<Ok<IEnumerable<RelMeseResponse>>, NotFound>> PostMesi
[FromServices] IStringLocalizer<Localization> localizer,
[FromServices] IMediator handler)
{
var authInfo = context.GetAuthInfo();
var authInfo = context.GetAuthInfo();

var mesi = await handler.Send(new RelMesiByIdEnteQuery(authInfo)
{
Anno = request.Anno
Anno = request.Anno
});

if (mesi.IsNullNotAny())
Expand Down Expand Up @@ -559,7 +561,7 @@ private async Task<IResult> GetDownloadFirmaAsync(
|| rel.TipologiaFattura!.ToLower().Contains("var")
|| rel.TipologiaFattura!.ToLower().Contains("semestrale")
|| rel.TipologiaFattura!.ToLower().Contains("annuale"))
return NotFound();
return NotFound();

var bytes = await storageService.ReadBytes(key);
await handler.Send(new RelDownloadCommand(authInfo)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@
"SelfCareOnBoarding:AuthToken": "SELFCAREONBOARDING_AUTHTOKEN",
"SupportAPIService:Endpoint": "SUPPORTAPISERVICE_ENDPOINT",
"SupportAPIService:RecipientCodeUri": "SUPPORTAPISERVICE_URI",
"SupportAPIService:AuthToken": "SUPPORTAPISERVICE_AUTHTOKEN"
"SupportAPIService:AuthToken": "SUPPORTAPISERVICE_AUTHTOKEN",
"StorageREL:StorageRELAccountName": "StorageRELAccountName",
"StorageREL:StorageRELAccountKey": "StorageRELAccountKey",
"StorageREL:StorageRELBlobContainerName": "StorageRELBlobContainerName",
"StorageREL:StorageRELCustomDns": "StorageRELCustomDns"
}
}
6 changes: 5 additions & 1 deletion src/Presentation/PortaleFatture.BE.Api/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@
"SelfCareOnBoarding:AuthToken": "SELFCAREONBOARDING_AUTHTOKEN",
"SupportAPIService:Endpoint": "SUPPORTAPISERVICE_ENDPOINT",
"SupportAPIService:RecipientCodeUri": "SUPPORTAPISERVICE_URI",
"SupportAPIService:AuthToken": "SUPPORTAPISERVICE_AUTHTOKEN"
"SupportAPIService:AuthToken": "SUPPORTAPISERVICE_AUTHTOKEN",
"StorageREL:StorageRELAccountName": "StorageRELAccountName",
"StorageREL:StorageRELAccountKey": "StorageRELAccountKey",
"StorageREL:StorageRELBlobContainerName": "StorageRELBlobContainerName",
"StorageREL:StorageRELCustomDns": "StorageRELCustomDns"
},
"Kestrel": {
"Limits": {
Expand Down
2 changes: 1 addition & 1 deletion src/Presentation/PortaleFatture.BE.EmailSender/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

// params
var anno = 2024;
var mese = 11;
var mese = 12;
var tipologiafattura = "PRIMO SALDO";
var data = DateTime.UtcNow.ItalianTime().ToString("yyyy-MM-dd HH:mm:ss");
var ricalcola = 0;
Expand Down
Loading

0 comments on commit 6ef29e7

Please sign in to comment.