Files
WhiteLagoon/WhiteLagoon.Web/Controllers/BookingController.cs
T
2025-05-20 11:46:50 -04:00

363 lines
14 KiB
C#

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Stripe;
using Stripe.Checkout;
using Syncfusion.DocIO;
using Syncfusion.DocIO.DLS;
using Syncfusion.DocIORenderer;
using Syncfusion.Drawing;
using Syncfusion.Pdf;
using System.Security.Claims;
using WhiteLagoon.Application.Common.Interfaces;
using WhiteLagoon.Application.Common.Utility;
using WhiteLagoon.Application.Contract;
using WhiteLagoon.Application.Services.Interface;
using WhiteLagoon.Domain.Entities;
using WhiteLagoon.Infrastructure.Repository;
namespace WhiteLagoon.Web.Controllers
{
public class BookingController : Controller
{
private readonly IBookingService _bookingService;
private readonly IWebHostEnvironment _webHostEnvironment;
private readonly IVillaService _villaService;
private readonly UserManager<ApplicationUser> _userManager;
private readonly IVillaNumberService _villaNumberService;
private readonly IPaymentService _paymentService;
private readonly IEmailService _emailService;
public BookingController(IBookingService bookingService,
IPaymentService paymentService,
IVillaService villaService, IVillaNumberService villaNumberService,
IWebHostEnvironment webHostEnvironment, UserManager<ApplicationUser> userManager,
IEmailService emailService)
{
_emailService = emailService;
_paymentService = paymentService;
_userManager = userManager;
_villaService = villaService;
_villaNumberService = villaNumberService;
_bookingService = bookingService;
_webHostEnvironment = webHostEnvironment;
}
[Authorize]
public IActionResult Index()
{
return View();
}
[Authorize]
public IActionResult FinalizeBooking(int villaId, DateOnly checkInDate, int nights)
{
var claimsIdentity = (ClaimsIdentity)User.Identity;
var userId = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier).Value;
ApplicationUser user = _userManager.FindByIdAsync(userId).GetAwaiter().GetResult();
Booking booking = new()
{
VillaId = villaId,
Villa = _villaService.GetVillaById(villaId),
CheckInDate = checkInDate,
Nights = nights,
CheckOutDate = checkInDate.AddDays(nights),
UserId = userId,
Phone=user.PhoneNumber,
Email=user.Email,
Name=user.Name
};
booking.TotalCost = booking.Villa.Price * nights;
return View(booking);
}
[Authorize]
[HttpPost]
public IActionResult FinalizeBooking(Booking booking)
{
var villa = _villaService.GetVillaById(booking.VillaId);
booking.TotalCost = villa.Price * booking.Nights;
booking.Status=SD.StatusPending;
booking.BookingDate = DateTime.Now;
if (!_villaService.IsVillaAvailableByDate(villa.Id,booking.Nights,booking.CheckInDate))
{
TempData["error"] = "Room has been sold out!";
//no rooms available
return RedirectToAction(nameof(FinalizeBooking), new
{
villaId = booking.VillaId,
checkInDate = booking.CheckInDate,
nights = booking.Nights
});
}
_bookingService.CreateBooking(booking);
var domain = Request.Scheme+"://"+Request.Host.Value+"/";
var options = _paymentService.CreateStripeSessionOptions(booking, villa, domain);
var session = _paymentService.CreateStripeSession(options);
_bookingService.UpdateStripePaymentID(booking.Id, session.Id, session.PaymentIntentId);
Response.Headers.Add("Location", session.Url);
return new StatusCodeResult(303);
}
[Authorize]
public IActionResult BookingConfirmation(int bookingId)
{
Booking bookingFromDb = _bookingService.GetBookingById(bookingId);
if (bookingFromDb.Status == SD.StatusPending)
{
//this is a pending order, we need to confirm if payment was successful
var service = new SessionService();
Session session = service.Get(bookingFromDb.StripeSessionId);
if (session.PaymentStatus == "paid")
{
_bookingService.UpdateStatus(bookingFromDb.Id, SD.StatusApproved,0);
_bookingService.UpdateStripePaymentID(bookingFromDb.Id,session.Id,session.PaymentIntentId);
_emailService.SendEmailAsync(bookingFromDb.Email,"Booking Confirmation - White Lagoon", "<p>Your booking has been confirmed. Booking ID - " + bookingFromDb.Id+"</p>");
}
}
return View(bookingId);
}
[Authorize]
public IActionResult BookingDetails(int bookingId)
{
Booking bookingFromDb = _bookingService.GetBookingById(bookingId);
if (bookingFromDb.VillaNumber==0 && bookingFromDb.Status == SD.StatusApproved)
{
var availableVillaNumber = AssignAvailableVillaNumberByVilla(bookingFromDb.VillaId);
bookingFromDb.VillaNumbers = _villaNumberService.GetAllVillaNumbers().Where(u => u.VillaId == bookingFromDb.VillaId
&& availableVillaNumber.Any(x => x == u.Villa_Number)).ToList();
}
return View(bookingFromDb);
}
[HttpPost]
[Authorize]
public IActionResult GenerateInvoice(int id, string downloadType)
{
string basePath = _webHostEnvironment.WebRootPath;
WordDocument document = new WordDocument();
// Load the template.
string dataPath = basePath + @"/exports/BookingDetails.docx";
using FileStream fileStream = new (dataPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
document.Open(fileStream, FormatType.Automatic);
//Update Template
Booking bookingFromDb = _bookingService.GetBookingById(id);
TextSelection textSelection = document.Find("xx_customer_name", false, true);
WTextRange textRange = textSelection.GetAsOneRange();
textRange.Text = bookingFromDb.Name;
textSelection = document.Find("xx_customer_phone", false, true);
textRange = textSelection.GetAsOneRange();
textRange.Text = bookingFromDb.Phone;
textSelection = document.Find("xx_customer_email", false, true);
textRange = textSelection.GetAsOneRange();
textRange.Text = bookingFromDb.Email;
textSelection = document.Find("XX_BOOKING_NUMBER", false, true);
textRange = textSelection.GetAsOneRange();
textRange.Text = "BOOKING ID - " + bookingFromDb.Id;
textSelection = document.Find("XX_BOOKING_DATE", false, true);
textRange = textSelection.GetAsOneRange();
textRange.Text = "BOOKING DATE - " + bookingFromDb.BookingDate.ToShortDateString();
textSelection = document.Find("xx_payment_date", false, true);
textRange = textSelection.GetAsOneRange();
textRange.Text = bookingFromDb.PaymentDate.ToShortDateString();
textSelection = document.Find("xx_checkin_date", false, true);
textRange = textSelection.GetAsOneRange();
textRange.Text = bookingFromDb.CheckInDate.ToShortDateString();
textSelection = document.Find("xx_checkout_date", false, true);
textRange = textSelection.GetAsOneRange();
textRange.Text = bookingFromDb.CheckOutDate.ToShortDateString(); ;
textSelection = document.Find("xx_booking_total", false, true);
textRange = textSelection.GetAsOneRange();
textRange.Text = bookingFromDb.TotalCost.ToString("c");
WTable table = new(document);
table.TableFormat.Borders.LineWidth = 1f;
table.TableFormat.Borders.Color = Color.Black;
table.TableFormat.Paddings.Top = 7f;
table.TableFormat.Paddings.Bottom = 7f;
table.TableFormat.Borders.Horizontal.LineWidth = 1f;
int rows = bookingFromDb.VillaNumber > 0 ? 3 : 2;
table.ResetCells(rows, 4);
WTableRow row0 = table.Rows[0];
row0.Cells[0].AddParagraph().AppendText("NIGHTS");
row0.Cells[0].Width=80;
row0.Cells[1].AddParagraph().AppendText("VILLA");
row0.Cells[1].Width = 220;
row0.Cells[2].AddParagraph().AppendText("PRICE PER NIGHT");
row0.Cells[3].AddParagraph().AppendText("TOTAL");
row0.Cells[3].Width = 80;
WTableRow row1 = table.Rows[1];
row1.Cells[0].AddParagraph().AppendText(bookingFromDb.Nights.ToString());
row1.Cells[0].Width = 80;
row1.Cells[1].AddParagraph().AppendText(bookingFromDb.Villa.Name);
row1.Cells[1].Width = 220;
row1.Cells[2].AddParagraph().AppendText((bookingFromDb.TotalCost/bookingFromDb.Nights).ToString("c"));
row1.Cells[3].AddParagraph().AppendText(bookingFromDb.TotalCost.ToString("c"));
row1.Cells[3].Width = 80;
if (bookingFromDb.VillaNumber > 0)
{
WTableRow row2 = table.Rows[2];
row2.Cells[0].Width = 80;
row2.Cells[1].AddParagraph().AppendText("Villa Number - " + bookingFromDb.VillaNumber.ToString());
row2.Cells[1].Width = 220;
row2.Cells[3].Width = 80;
}
WTableStyle tableStyle = document.AddTableStyle("CustomStyle") as WTableStyle;
tableStyle.TableProperties.RowStripe = 1;
tableStyle.TableProperties.ColumnStripe = 2;
tableStyle.TableProperties.Paddings.Top = 2;
tableStyle.TableProperties.Paddings.Bottom = 1;
tableStyle.TableProperties.Paddings.Left = 5.4f;
tableStyle.TableProperties.Paddings.Right = 5.4f;
ConditionalFormattingStyle firstRowStyle = tableStyle.ConditionalFormattingStyles.Add(ConditionalFormattingType.FirstRow);
firstRowStyle.CharacterFormat.Bold = true;
firstRowStyle.CharacterFormat.TextColor = Color.FromArgb(255, 255, 255, 255);
firstRowStyle.CellProperties.BackColor = Color.Black;
table.ApplyStyle("CustomStyle");
TextBodyPart bodyPart = new(document);
bodyPart.BodyItems.Add(table);
document.Replace("<ADDTABLEHERE>", bodyPart, false, false);
using DocIORenderer renderer = new ();
MemoryStream stream = new();
if (downloadType == "word")
{
document.Save(stream, FormatType.Docx);
stream.Position = 0;
return File(stream, "application/docx", "BookingDetails.docx");
}
else
{
PdfDocument pdfDocument = renderer.ConvertToPDF(document);
pdfDocument.Save(stream);
stream.Position = 0;
return File(stream, "application/pdf", "BookingDetails.pdf");
}
}
[HttpPost]
[Authorize(Roles = SD.Role_Admin)]
public IActionResult CheckIn(Booking booking)
{
_bookingService.UpdateStatus(booking.Id, SD.StatusCheckedIn, booking.VillaNumber);
TempData["Success"] = "Booking Updated Successfully.";
return RedirectToAction(nameof(BookingDetails), new { bookingId = booking.Id });
}
[HttpPost]
[Authorize(Roles = SD.Role_Admin)]
public IActionResult CheckOut(Booking booking)
{
_bookingService.UpdateStatus(booking.Id, SD.StatusCompleted , booking.VillaNumber);
TempData["Success"] = "Booking Completed Successfully.";
return RedirectToAction(nameof(BookingDetails), new { bookingId = booking.Id });
}
[HttpPost]
[Authorize(Roles = SD.Role_Admin)]
public IActionResult CancelBooking(Booking booking)
{
_bookingService.UpdateStatus(booking.Id, SD.StatusCancelled, 0);
TempData["Success"] = "Booking Cancelled Successfully.";
return RedirectToAction(nameof(BookingDetails), new { bookingId = booking.Id });
}
private List<int> AssignAvailableVillaNumberByVilla(int villaId)
{
List<int> availableVillaNumbers = new();
var villaNumbers = _villaNumberService.GetAllVillaNumbers().Where(u => u.VillaId == villaId);
var checkedInVilla = _bookingService.GetCheckedInVillaNumbers(villaId);
foreach(var villaNumber in villaNumbers)
{
if (!checkedInVilla.Contains(villaNumber.Villa_Number))
{
availableVillaNumbers.Add(villaNumber.Villa_Number);
}
}
return availableVillaNumbers;
}
#region API Calls
[HttpGet]
[Authorize]
public IActionResult GetAll(string status)
{
IEnumerable<Booking> objBookings;
string userId = "";
if (string.IsNullOrEmpty(status))
{
status = "";
}
if (!User.IsInRole(SD.Role_Admin))
{
var claimsIdentity = (ClaimsIdentity)User.Identity;
userId = claimsIdentity.FindFirst(ClaimTypes.NameIdentifier).Value;
}
objBookings = _bookingService.GetAllBookings(userId, status);
return Json(new { data = objBookings });
}
#endregion
}
}