using Indotalent.Infrastructure.Database; using MediatR; using Microsoft.EntityFrameworkCore; namespace Indotalent.Features.Sales.Invoice.Cqrs; public class InvoiceSalesOrderItemResponse { public string? Id { get; set; } public string? ProductId { get; set; } public string? ProductName { get; set; } public string? Summary { get; set; } public decimal? UnitPrice { get; set; } public double? Quantity { get; set; } public decimal? Total { get; set; } } public class GetInvoiceByIdResponse { public string? Id { get; set; } public string? AutoNumber { get; set; } public DateTime? InvoiceDate { get; set; } public Data.Enums.InvoiceStatus InvoiceStatus { get; set; } public string? Description { get; set; } public string? SalesOrderId { get; set; } public string? SalesOrderAutoNumber { get; set; } public string? CustomerName { get; set; } public string? CustomerStreet { get; set; } public string? CustomerCity { get; set; } public string? CompanyName { get; set; } public string? CompanyStreet { get; set; } public string? CompanyCity { get; set; } public string? CompanyState { get; set; } public string? CompanyZipCode { get; set; } public string? CompanyPhone { get; set; } public string? CurrencySymbol { get; set; } public decimal? BeforeTaxAmount { get; set; } public decimal? TaxAmount { get; set; } public decimal? AfterTaxAmount { get; set; } public DateTimeOffset? CreatedAt { get; set; } public string? CreatedBy { get; set; } public DateTimeOffset? UpdatedAt { get; set; } public string? UpdatedBy { get; set; } public List Items { get; set; } = new(); } public record GetInvoiceByIdQuery(string Id) : IRequest; public class GetInvoiceByIdHandler : IRequestHandler { private readonly AppDbContext _context; public GetInvoiceByIdHandler(AppDbContext context) => _context = context; public async Task Handle(GetInvoiceByIdQuery request, CancellationToken cancellationToken) { var company = await _context.Company .AsNoTracking() .Include(x => x.Currency) .OrderByDescending(x => x.IsDefault) .FirstOrDefaultAsync(cancellationToken); return await _context.Invoice .AsNoTracking() .Include(x => x.SalesOrder) .ThenInclude(x => x!.Customer) .Include(x => x.SalesOrder) .ThenInclude(x => x!.SalesOrderItemList) .ThenInclude(x => x.Product) .Where(x => x.Id == request.Id) .Select(x => new GetInvoiceByIdResponse { Id = x.Id, AutoNumber = x.AutoNumber, InvoiceDate = x.InvoiceDate, InvoiceStatus = x.InvoiceStatus, Description = x.Description, SalesOrderId = x.SalesOrderId, SalesOrderAutoNumber = x.SalesOrder!.AutoNumber, CustomerName = x.SalesOrder!.Customer!.Name, CustomerStreet = x.SalesOrder!.Customer!.Street, CustomerCity = x.SalesOrder!.Customer!.City, CompanyName = company != null ? company.Name : string.Empty, CompanyStreet = company != null ? company.StreetAddress : string.Empty, CompanyCity = company != null ? company.City : string.Empty, CompanyState = company != null ? company.StateProvince : string.Empty, CompanyZipCode = company != null ? company.ZipCode : string.Empty, CompanyPhone = company != null ? company.Phone : string.Empty, CurrencySymbol = company != null && company.Currency != null ? company.Currency.Symbol : "IDR", BeforeTaxAmount = x.SalesOrder!.BeforeTaxAmount, TaxAmount = x.SalesOrder!.TaxAmount, AfterTaxAmount = x.SalesOrder!.AfterTaxAmount, CreatedAt = x.CreatedAt, CreatedBy = x.CreatedBy, UpdatedAt = x.UpdatedAt, UpdatedBy = x.UpdatedBy, Items = x.SalesOrder!.SalesOrderItemList.Select(i => new InvoiceSalesOrderItemResponse { Id = i.Id, ProductId = i.ProductId, ProductName = i.Product!.Name, Summary = i.Summary, UnitPrice = i.UnitPrice, Quantity = i.Quantity, Total = i.Total }).ToList() }).FirstOrDefaultAsync(cancellationToken); } }