This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
using LiteCharms.Features.Extensions;
|
||||
using LiteCharms.Features.Models;
|
||||
using LiteCharms.Features.TechShop.Extensions;
|
||||
using LiteCharms.Features.TechShop.Postgres;
|
||||
using LiteCharms.Features.TechShop.Quotes.Models;
|
||||
|
||||
namespace LiteCharms.Features.TechShop.Quotes;
|
||||
|
||||
public class QuoteService(IDbContextFactory<ShopDbContext> contextFactory)
|
||||
{
|
||||
public async ValueTask<Result> AssignQuoteToOrderAsync(Guid quoteId, Guid orderId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var quote = await context.Quotes.FirstOrDefaultAsync(o => o.Id == quoteId, cancellationToken);
|
||||
|
||||
if (quote is null)
|
||||
return Result.Fail(new Error($"Quote with id {orderId} not found"));
|
||||
|
||||
if (!await context.Orders.AnyAsync(q => q.Id == orderId, cancellationToken))
|
||||
return Result.Fail(new Error($"Order with id {quoteId} not found"));
|
||||
|
||||
if (quote.OrderId == orderId)
|
||||
return Result.Fail(new Error($"Quote with id {quoteId} is already assigned to order with id {orderId}"));
|
||||
|
||||
quote.OrderId = orderId;
|
||||
quote.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
return await context.SaveChangesAsync(cancellationToken) > 0
|
||||
? Result.Ok()
|
||||
: Result.Fail(new Error($"Failed to assign quote with id {quoteId} to order with id {orderId}"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result> AssignQuoteToShoppingCartAsync(Guid quoteId, Guid shoppingCartId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var quote = await context.Quotes.FirstOrDefaultAsync(o => o.Id == quoteId, cancellationToken);
|
||||
|
||||
if (quote is null)
|
||||
return Result.Fail(new Error($"Quote with id {quoteId} not found"));
|
||||
|
||||
if (!await context.ShoppingCarts.AnyAsync(q => q.Id == shoppingCartId, cancellationToken))
|
||||
return Result.Fail(new Error($"Shopping Cart with id {shoppingCartId} not found"));
|
||||
|
||||
quote.ShoppingCartId = shoppingCartId;
|
||||
quote.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
return await context.SaveChangesAsync(cancellationToken) > 0
|
||||
? Result.Ok()
|
||||
: Result.Fail(new Error("Failed to assign quote to shopping cart"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result<Quote[]>> GetCustomerQuotesAsync(Guid customerId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
if (!await context.Customers.AnyAsync(c => c.Id == customerId, cancellationToken))
|
||||
return Result.Fail<Quote[]>(new Error($"Customer with Id {customerId} does not exist."));
|
||||
|
||||
var quotes = await context.Quotes.AsNoTracking()
|
||||
.Where(q => q.CustomerId == customerId).ToArrayAsync(cancellationToken);
|
||||
|
||||
return quotes?.Length > 0
|
||||
? Result.Ok(quotes.Select(q => q.ToModel()).ToArray())
|
||||
: Result.Fail<Quote[]>(new Error($"No quotes found for customer with Id {customerId}."));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail<Quote[]>(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result<Quote>> GetQuoteAsync(Guid quoteId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
await using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var quote = await context.Quotes.AsNoTracking().FirstOrDefaultAsync(q => q.Id == quoteId, cancellationToken);
|
||||
|
||||
return quote is not null
|
||||
? Result.Ok(quote.ToModel())
|
||||
: Result.Fail<Quote>(new Error($"Quote with ID {quoteId} not found."));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail<Quote>(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result<Quote[]>> GetQuotesAsync(DateRange range, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fromDate = range.From.ToDateTime(TimeOnly.MinValue);
|
||||
var toDate = range.To.ToDateTime(TimeOnly.MaxValue);
|
||||
|
||||
using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var quotes = await context.Quotes.AsNoTracking()
|
||||
.OrderByDescending(o => o.CreatedAt)
|
||||
.Where(o => o.CreatedAt >= fromDate && o.CreatedAt <= toDate)
|
||||
.Take(range.MaxRecords)
|
||||
.ToArrayAsync(cancellationToken);
|
||||
|
||||
return quotes?.Length > 0
|
||||
? Result.Ok(quotes.Select(o => o.ToModel()).ToArray())
|
||||
: Result.Fail<Quote[]>(new Error($"No quotes found for the specified date range {range.From} - {range.To}."));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail<Quote[]>(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask<Result> UpdateQuoteStatusAsync(Guid quoteId, QuoteStatus status, CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var context = await contextFactory.CreateDbContextAsync(cancellationToken);
|
||||
|
||||
var quote = await context.Quotes.FirstOrDefaultAsync(q => q.Id == quoteId, cancellationToken);
|
||||
|
||||
if (quote is null)
|
||||
return Result.Fail(new Error("Quote not found."));
|
||||
|
||||
quote.Status = status;
|
||||
quote.UpdatedAt = DateTime.UtcNow;
|
||||
|
||||
return await context.SaveChangesAsync(cancellationToken) > 0
|
||||
? Result.Ok()
|
||||
: Result.Fail(new Error("Failed to update quote status."));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Result.Fail(new Error(ex.Message).CausedBy(ex));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user