feat: Enhance booking functionality with invoice management and dashboard summary

- Added customerId to guest booking requests for better identification.
- Implemented new endpoints for managing booking invoices and dashboard summaries.
- Created BookingInvoice and BookingDashboardSummary DTOs to support new features.
- Updated Booking and BookingInvoice models to include payment method and timestamps.
- Enhanced BookingService to handle invoice creation upon payment confirmation.
- Modified BookingRepository to support CRUD operations for BookingInvoice.
- Updated TenantDbContext to include BookingInvoice DbSet and relevant configurations.
- Improved error handling and validation for booking completion and payment processes.
This commit is contained in:
2026-10-01 03:46:03 +05:30
parent 6abef835e8
commit 51f0021e27
16 changed files with 501 additions and 45 deletions
+47 -6
View File
@@ -81,12 +81,6 @@ namespace Fitness_core_BE.Repos
.Where(b => b.FKClientId == clientId && b.Status == "Confirmed" && b.EndTime < now)
.ExecuteUpdateAsync(s => s.SetProperty(b => b.Status, "NoShow"));
public Task<List<Booking>> GetOverdueCheckedInBookingsAsync(Guid clientId, DateTime now)
=> _context.Bookings
.Include(b => b.RfidTag)
.Where(b => b.FKClientId == clientId && b.Status == "CheckedIn" && b.EndTime < now)
.ToListAsync();
public async Task<bool> TryClaimRfidTagAsync(Guid tagId, DateTime now)
{
var rows = await _context.RfidTags
@@ -96,5 +90,52 @@ namespace Fitness_core_BE.Repos
.SetProperty(t => t.UpdatedAt, now));
return rows > 0;
}
public async Task<BookingInvoice> CreateBookingInvoice(BookingInvoice invoice)
{
invoice.BookingInvoiceId = Guid.NewGuid();
invoice.IssuedAt = DateTime.UtcNow;
_context.BookingInvoices.Add(invoice);
return invoice;
}
public Task<List<BookingInvoice>> GetBookingInvoices(Guid clientId, DateTime? fromUtc, DateTime? toUtc)
{
var query = _context.BookingInvoices.Where(i => i.FKClientId == clientId);
if (fromUtc.HasValue) query = query.Where(i => i.IssuedAt >= fromUtc.Value);
if (toUtc.HasValue) query = query.Where(i => i.IssuedAt <= toUtc.Value);
return query.OrderByDescending(i => i.IssuedAt).ToListAsync();
}
public Task<BookingInvoice?> GetBookingInvoiceById(Guid bookingInvoiceId)
=> _context.BookingInvoices.FirstOrDefaultAsync(i => i.BookingInvoiceId == bookingInvoiceId);
public async Task<(int bookingsToday, decimal revenueToday, int checkedInNow, int upcomingConfirmed, decimal outstandingUnpaid)>
GetDashboardSummaryAsync(Guid clientId, DateTime now)
{
var todayStart = now.Date;
var todayEnd = todayStart.AddDays(1);
var bookingsToday = await _context.Bookings
.CountAsync(b => b.FKClientId == clientId && b.StartTime >= todayStart && b.StartTime < todayEnd);
var revenueToday = await _context.Bookings
.Where(b => b.FKClientId == clientId && b.PaidAt >= todayStart && b.PaidAt < todayEnd)
.SumAsync(b => (decimal?)b.AmountCharged) ?? 0m;
var checkedInNow = await _context.Bookings
.CountAsync(b => b.FKClientId == clientId && b.Status == "CheckedIn");
var upcomingConfirmed = await _context.Bookings
.CountAsync(b => b.FKClientId == clientId && b.Status == "Confirmed" && b.StartTime > now);
var outstandingUnpaid = await _context.Bookings
.Where(b => b.FKClientId == clientId && b.PaymentStatus == "Unpaid")
.SumAsync(b => (decimal?)b.AmountCharged) ?? 0m;
return (bookingsToday, revenueToday, checkedInNow, upcomingConfirmed, outstandingUnpaid);
}
}
}