Files
2026-07-01 11:21:10 +09:00

160 lines
6.0 KiB
C#

namespace TaxBaik.Web.Services.AdminClients;
using System.Text.Json;
using TaxBaik.Domain.Entities;
public interface IRevenueTrackingBrowserClient
{
Task<List<RevenueTracking>> GetAllAsync(CancellationToken ct = default);
Task<List<RevenueTracking>> GetByClientIdAsync(int clientId, CancellationToken ct = default);
Task<List<RevenueTracking>> GetPendingPaymentsAsync(CancellationToken ct = default);
Task<List<RevenueTracking>> GetMonthlyRevenueAsync(int year, int month, CancellationToken ct = default);
Task<decimal> GetTotalRevenueAsync(DateTime startDate, DateTime endDate, CancellationToken ct = default);
Task<int> CreateAsync(int clientId, string invoiceNumber, DateTime invoiceDate, decimal amount,
string? serviceType = null, DateTime? dueDate = null, CancellationToken ct = default);
Task MarkPaidAsync(int id, DateTime paymentDate, CancellationToken ct = default);
Task DeleteAsync(int id, CancellationToken ct = default);
}
public class RevenueTrackingBrowserClient(HttpClient httpClient, ITokenStore tokenStore, ILogger<RevenueTrackingBrowserClient> logger)
: IRevenueTrackingBrowserClient
{
private const string BaseUrl = "/api/revenuetracking";
private void EnsureAuthHeader()
{
if (!string.IsNullOrEmpty(tokenStore.AccessToken))
httpClient.DefaultRequestHeaders.Authorization = new("Bearer", tokenStore.AccessToken);
else
httpClient.DefaultRequestHeaders.Authorization = null;
}
public async Task<List<RevenueTracking>> GetAllAsync(CancellationToken ct = default)
{
try
{
EnsureAuthHeader();
return await httpClient.GetFromJsonAsync<List<RevenueTracking>>($"{BaseUrl}", ct) ?? [];
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to get revenue tracking");
return [];
}
}
public async Task<List<RevenueTracking>> GetByClientIdAsync(int clientId, CancellationToken ct = default)
{
try
{
EnsureAuthHeader();
return await httpClient.GetFromJsonAsync<List<RevenueTracking>>($"{BaseUrl}/client/{clientId}", ct) ?? [];
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to get revenue for client {ClientId}", clientId);
return [];
}
}
public async Task<List<RevenueTracking>> GetPendingPaymentsAsync(CancellationToken ct = default)
{
try
{
EnsureAuthHeader();
var response = await httpClient.GetFromJsonAsync<JsonElement>($"{BaseUrl}/pending", ct);
if (response.TryGetProperty("data", out var data))
return System.Text.Json.JsonSerializer.Deserialize<List<RevenueTracking>>(data.GetRawText()) ?? [];
return [];
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to get pending payments");
return [];
}
}
public async Task<List<RevenueTracking>> GetMonthlyRevenueAsync(int year, int month, CancellationToken ct = default)
{
try
{
EnsureAuthHeader();
var response = await httpClient.GetFromJsonAsync<JsonElement>($"{BaseUrl}/monthly?year={year}&month={month}", ct);
if (response.TryGetProperty("data", out var data))
return System.Text.Json.JsonSerializer.Deserialize<List<RevenueTracking>>(data.GetRawText()) ?? [];
return [];
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to get monthly revenue {Year}-{Month}", year, month);
return [];
}
}
public async Task<decimal> GetTotalRevenueAsync(DateTime startDate, DateTime endDate, CancellationToken ct = default)
{
try
{
EnsureAuthHeader();
var response = await httpClient.GetFromJsonAsync<JsonElement>(
$"{BaseUrl}/total?startDate={startDate:yyyy-MM-dd}&endDate={endDate:yyyy-MM-dd}", ct);
if (response.TryGetProperty("total", out var totalValue))
return System.Text.Json.JsonSerializer.Deserialize<decimal>(totalValue.GetRawText());
return 0;
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to get total revenue");
return 0;
}
}
public async Task<int> CreateAsync(int clientId, string invoiceNumber, DateTime invoiceDate, decimal amount,
string? serviceType = null, DateTime? dueDate = null, CancellationToken ct = default)
{
try
{
EnsureAuthHeader();
var request = new { clientId, invoiceNumber, invoiceDate, amount, serviceType, dueDate };
var response = await httpClient.PostAsJsonAsync(BaseUrl, request, ct);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<JsonElement>(cancellationToken: ct);
return result.TryGetProperty("id", out var idProp) ? idProp.GetInt32() : 0;
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to create revenue tracking");
return 0;
}
}
public async Task MarkPaidAsync(int id, DateTime paymentDate, CancellationToken ct = default)
{
try
{
EnsureAuthHeader();
var request = new { paymentDate };
var response = await httpClient.PutAsJsonAsync($"{BaseUrl}/{id}/paid", request, ct);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to mark payment {Id}", id);
}
}
public async Task DeleteAsync(int id, CancellationToken ct = default)
{
try
{
EnsureAuthHeader();
var response = await httpClient.DeleteAsync($"{BaseUrl}/{id}", ct);
response.EnsureSuccessStatusCode();
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to delete revenue tracking {Id}", id);
}
}
}