Skip to content

Commit be5dfba

Browse files
committed
Version 4.0.95
1 parent b116757 commit be5dfba

File tree

11 files changed

+76
-65
lines changed

11 files changed

+76
-65
lines changed

Abstractions/BaseFiscalApiService.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,6 @@ public virtual Task<ApiResponse<T>> UpdateAsync(string id, T entity)
7272

7373
public virtual Task<ApiResponse<bool>> DeleteAsync(string id)
7474
=> HttpClient.DeleteAsync(BuildEndpoint(id));
75+
7576
}
7677
}

Common/FiscalApiOptions.cs renamed to Common/FiscalapiSettings.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace Fiscalapi.Common
22
{
3-
public class FiscalApiOptions
3+
public class FiscalapiSettings
44
{
55
public string ApiUrl { get; set; }
66
public string ApiKey { get; set; }

Http/FiscalApiHttpClient.cs

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -47,53 +47,14 @@ public async Task<ApiResponse<T>> PatchAsync<T>(string endpoint, object payload)
4747
public async Task<ApiResponse<bool>> DeleteAsync(string endpoint)
4848
=> await SendRequestAsync<bool>(HttpMethod.Delete, endpoint);
4949

50-
//private async Task<ApiResponse<T>> SendRequestAsync<T>(
51-
// HttpMethod method,
52-
// string endpoint,
53-
// object content = null
54-
//)
55-
//{
56-
// var request = new HttpRequestMessage(method, endpoint);
57-
58-
// if (content != null)
59-
// {
60-
// var json = JsonConvert.SerializeObject(content, _jsonSettings);
61-
// request.Content = new StringContent(json, Encoding.UTF8, "application/json");
62-
// }
63-
64-
// var response = await _httpClient.SendAsync(request);
65-
// var responseContent = await response.Content.ReadAsStringAsync();
66-
67-
// return response.IsSuccessStatusCode
68-
// ? JsonConvert.DeserializeObject<ApiResponse<T>>(responseContent, _jsonSettings)
69-
// : HandleFailureAsync<T>(responseContent);
70-
//}
71-
72-
//private ApiResponse<T> HandleFailureAsync<T>(string responseContent)
73-
//{
74-
// var failureResponse =
75-
// JsonConvert.DeserializeObject<ApiResponse<List<ValidationFailure>>>(responseContent, _jsonSettings);
76-
77-
// var failures = failureResponse.Data;
78-
79-
// var friendlyErrorMessage = "";
80-
// if (failures != null && failures.Count > 0)
81-
// {
82-
// friendlyErrorMessage = string.Join("; ",
83-
// failures.Select(x => $"{x.PropertyName}: {x.ErrorMessage}"));
84-
// }
85-
86-
// return new ApiResponse<T>
87-
// {
88-
// Succeeded = false,
89-
// HttpStatusCode = failureResponse.HttpStatusCode,
90-
// Message = failureResponse.Message,
91-
// Details = !string.IsNullOrEmpty(friendlyErrorMessage)
92-
// ? friendlyErrorMessage
93-
// : failureResponse.Details,
94-
// Data = default
95-
// };
96-
//}
50+
public async Task<ApiResponse<T>> DeleteAsync<T>(string endpoint, object payload)
51+
{
52+
// SendRequestAsync<T>(HttpMethod.Delete, endpoint, payload);
53+
54+
return await SendRequestAsync<T>(HttpMethod.Delete, endpoint, payload);
55+
}
56+
57+
9758
public async Task<ApiResponse<T>> SendRequestAsync<T>(HttpMethod method, string endpoint, object content = null)
9859
{
9960
var request = new HttpRequestMessage(method, endpoint);
@@ -117,12 +78,15 @@ private ApiResponse<T> HandleFailureResponse<T>(string responseContent, int stat
11778
try
11879
{
11980
// First try to deserialize as a generic response
120-
var failureResponse = JsonConvert.DeserializeObject<ApiResponse<object>>(responseContent, _jsonSettings);
81+
var failureResponse =
82+
JsonConvert.DeserializeObject<ApiResponse<object>>(responseContent, _jsonSettings);
12183

12284
// If status is 400, try to deserialize ValidationFailures
12385
if (statusCode == 400)
12486
{
125-
var validationResponse = JsonConvert.DeserializeObject<ApiResponse<List<ValidationFailure>>>(responseContent, _jsonSettings);
87+
var validationResponse =
88+
JsonConvert.DeserializeObject<ApiResponse<List<ValidationFailure>>>(responseContent,
89+
_jsonSettings);
12690
var failures = validationResponse?.Data;
12791

12892
var validationErrors = failures != null && failures.Count > 0
@@ -163,5 +127,4 @@ private ApiResponse<T> HandleFailureResponse<T>(string responseContent, int stat
163127
}
164128
}
165129
}
166-
}
167-
130+
}

Http/FiscalApiHttpClientFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public static class FiscalApiHttpClientFactory
1111
private static readonly ConcurrentDictionary<string, Lazy<HttpClient>> Clients =
1212
new ConcurrentDictionary<string, Lazy<HttpClient>>();
1313

14-
public static IFiscalApiHttpClient Create(FiscalApiOptions options)
14+
public static IFiscalApiHttpClient Create(FiscalapiSettings options)
1515
{
1616
if (options == null) throw new ArgumentNullException(nameof(options));
1717

Http/IFiscalApiHttpClient.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@ public interface IFiscalApiHttpClient
1111
Task<ApiResponse<T>> PutAsync<T>(string endpoint, object payload);
1212
Task<ApiResponse<T>> PatchAsync<T>(string endpoint, object payload);
1313
Task<ApiResponse<bool>> DeleteAsync(string endpoint);
14+
Task<ApiResponse<T>> DeleteAsync<T>(string endpoint, object payload);
1415
}
1516
}

Models/ApiKey.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11

22
using Fiscalapi.Common;
3-
using Newtonsoft.Json;
43

54
namespace Fiscalapi.Models
65
{

Models/TaxFile.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using Fiscalapi.Common;
3-
using Newtonsoft.Json;
43

54
namespace Fiscalapi.Models
65
{
@@ -9,9 +8,7 @@ public class TaxFile : BaseDto
98
/// <summary>
109
/// PersonId who owns the tax file
1110
/// </summary>
12-
[JsonProperty("userId")]
1311
public string PersonId { get; set; }
14-
1512
public string Tin { get; set; } // RFC (Tax Identification Number)
1613
public string Base64File { get; set; }
1714
public FileType FileType { get; set; }

ServiceCollectionExtensions.cs

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,76 @@
33
using Fiscalapi.Abstractions;
44
using Fiscalapi.Common;
55
using Fiscalapi.Services;
6+
using Microsoft.Extensions.Configuration;
67
using Microsoft.Extensions.DependencyInjection;
78
using Microsoft.Extensions.Options;
89

910
namespace FiscalApi
1011
{
1112
public static class ServiceCollectionExtensions
1213
{
14+
/// <summary>
15+
/// 1) Método de extensión que permite configurar <see cref="FiscalapiSettings"/>
16+
/// directamente mediante una expresión lambda.
17+
/// </summary>
18+
/// <param name="services">Contenedor de dependencias</param>
19+
/// <param name="configureSettings">Acción de configuración para <see cref="FiscalapiSettings"/></param>
20+
/// <returns></returns>
1321
public static IServiceCollection AddFiscalApi(
1422
this IServiceCollection services,
15-
Action<FiscalApiOptions> configureSettings)
23+
Action<FiscalapiSettings> configureSettings)
1624
{
25+
// Registra la configuración (Action<FiscalApiOptions>)
1726
services.Configure(configureSettings);
1827

19-
services.AddSingleton<IFiscalApiClient>(sp =>
28+
// Registra IFiscalApiClient con alcance 'Scoped'
29+
services.AddScoped<IFiscalApiClient>(sp =>
2030
{
21-
var settings = sp.GetRequiredService<IOptions<FiscalApiOptions>>().Value;
31+
var settings = sp.GetRequiredService<IOptions<FiscalapiSettings>>().Value;
2232
return FiscalApiClient.Create(settings);
2333
});
2434

2535
return services;
2636
}
2737

38+
/// <summary>
39+
/// 2) Método de extensión que lee la configuración directamente de la sección
40+
/// "FiscalapiSettings" del archivo de configuración (appsettings.json).
41+
/// Lanza una excepción si la sección no existe o está vacía.
42+
/// </summary>
43+
/// <param name="services">Contenedor de dependencias</param>
44+
/// <returns></returns>
45+
public static IServiceCollection AddFiscalApi(this IServiceCollection services)
46+
{
47+
using (var serviceProvider = services.BuildServiceProvider())
48+
{
49+
var configuration = serviceProvider.GetService<IConfiguration>();
50+
if (configuration == null)
51+
throw new InvalidOperationException("No se pudo obtener IConfiguration del contenedor...");
52+
53+
const string defaultSectionName = "FiscalapiSettings";
54+
var configSection = configuration.GetSection(defaultSectionName);
55+
56+
if (!configSection.Exists())
57+
throw new InvalidOperationException(
58+
$"No se encontró la sección '{defaultSectionName}' en la configuración. " +
59+
"Verifica que exista en tu appsettings.json.");
60+
61+
62+
services.Configure<FiscalapiSettings>(options => configSection.Bind(options));
63+
}
64+
65+
// Registra IFiscalApiClient como Scoped
66+
services.AddScoped<IFiscalApiClient>(sp =>
67+
{
68+
var settings = sp.GetRequiredService<IOptions<FiscalapiSettings>>().Value;
69+
return FiscalApiClient.Create(settings);
70+
});
71+
72+
return services;
73+
}
74+
75+
2876
/// <summary>
2977
/// Encode string to base64
3078
/// </summary>

Services/FiscalApiClient.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class FiscalApiClient : IFiscalApiClient
1616
public ITaxFileService TaxFiles { get; }
1717

1818

19-
private FiscalApiClient(FiscalApiOptions settings)
19+
private FiscalApiClient(FiscalapiSettings settings)
2020
{
2121
var httpClient = FiscalApiHttpClientFactory.Create(settings);
2222
var apiVersion = settings.ApiVersion;
@@ -31,7 +31,7 @@ private FiscalApiClient(FiscalApiOptions settings)
3131
TaxFiles = new TaxFileService(httpClient, apiVersion);
3232
}
3333

34-
public static IFiscalApiClient Create(FiscalApiOptions settings)
34+
public static IFiscalApiClient Create(FiscalapiSettings settings)
3535
{
3636
if (settings == null)
3737
throw new ArgumentNullException(nameof(settings));
@@ -41,7 +41,7 @@ public static IFiscalApiClient Create(FiscalApiOptions settings)
4141
}
4242

4343

44-
private static void ValidateSettings(FiscalApiOptions settings)
44+
private static void ValidateSettings(FiscalapiSettings settings)
4545
{
4646
if (string.IsNullOrEmpty(settings.ApiUrl))
4747
throw new ArgumentException("ApiUrl is required", nameof(settings.ApiUrl));

Services/InvoiceService.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,10 @@ public async Task<ApiResponse<CancelInvoiceResponse>> CancelAsync(CancelInvoiceR
4949
if (requestModel == null)
5050
throw new ArgumentNullException(nameof(requestModel));
5151

52+
// var endpoint = BuildEndpoint("cancel");
53+
5254
// POST /api/v4/invoices/cancel
53-
return await HttpClient.PostAsync<CancelInvoiceResponse>(BuildEndpoint("cancel"), requestModel);
55+
return await HttpClient.DeleteAsync<CancelInvoiceResponse>(BuildEndpoint(), requestModel);
5456
}
5557

5658
public async Task<ApiResponse<FileResponse>> GetPdfAsync(CreatePdfRequest requestModel)

0 commit comments

Comments
 (0)