using Azure.Core; using Data.SeaHavenIndustries; using Microsoft.AspNetCore.Components.Forms; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.WebUtilities; using Microsoft.EntityFrameworkCore; using Microsoft.VisualBasic; using SeaHavenIndustries.Data.IRepository; using SeaHavenIndustries.Helper; using SeaHavenIndustries.Helper.ViewModels; using SeaHavenIndustries.ViewModel; using System.Security.Claims; using System.Security.Cryptography; using System.Text; namespace SeaHavenIndustries.Data.Services { public class WorkorderService : IWorkOrderRepository { private readonly ApplicationDbContext _context; private readonly IHttpContextAccessor _httpContextAccessor; private UserManager _userManager; private UploadFileHp _uploadFileHelper; private readonly SendMessage _sendemail; private readonly BlazorWorkOrderSunsetGuard _sunsetGuard; public WorkorderService( SendMessage sendemail, ApplicationDbContext context, IHttpContextAccessor httpContextAccessor, UserManager userManager, UploadFileHp uploadFileHelper, BlazorWorkOrderSunsetGuard sunsetGuard) { _context = context; _httpContextAccessor = httpContextAccessor; _userManager = userManager; _uploadFileHelper = uploadFileHelper; _sendemail = sendemail; _sunsetGuard = sunsetGuard; } public async Task> Getworkorder() { _context.ChangeTracker.Clear(); // Use ChangeTracker.Clear() instead of setting EntityState.Detached var data = await _context.workOrders.Where(w => w.istemplate != true).Include(w => w.Locations).Include(w => w.AssignToUser).ToListAsync(); return data; } public async Task> Getworkorders() { _context.ChangeTracker.Clear(); var query = _context.workOrders .Where(w => w.istemplate != true) .AsSplitQuery() .Include(w => w.Locations) .Include(w => w.AssignToUser).Select(s=>new WorkorderFilterVM { Id= s.Id, Priority= s.Priority, Status= s.Status, WorkerOrderNumber = s.WorkerOrderNumber, WorkerOrderTitle = s.WorkerOrderTitle, DueDate = s.DueDate, AssignToUserName=s.AssignToUser.FirstName, LocationName=s.Locations.Name, }) .AsQueryable(); // Apply filter manually //if (!string.IsNullOrEmpty(filter)) //{ // if (filter.Contains("Locations.Name")) // { // var locationFilter = filter.Split('=').LastOrDefault()?.Trim(); // query = query.Where(w => w.Locations.Name.Contains(locationFilter)); // } // if (filter.Contains("AssignToUser.FirstName")) // { // var assignToUserFilter = filter.Split('=').LastOrDefault()?.Trim(); // query = query.Where(w => w.AssignToUser.FirstName.Contains(assignToUserFilter)); // } //} // Apply sorting manually //if (!string.IsNullOrEmpty(orderBy)) //{ // if (orderBy.Contains("Locations.Name")) // { // query = query.OrderBy(w => w.Locations.Name); // } // if (orderBy.Contains("AssignToUser.FirstName")) // { // query = query.OrderBy(w => w.AssignToUser.FirstName); // } //} return query; } public async Task> GetWorkOrderFilter(string[] assignto, int[]? location, string[]? priority, string[]? status, string[]? duedate, string search, string sort, string sortby) { _context.ChangeTracker.Clear(); try { if (sort == "Sort Order" && sortby == "Sort By" && assignto.Count() == 0 && (duedate == null || duedate.Count() == 0) && location.Count() == 0 && (priority == null || priority.Count() == 0) && (status == null || status.Count() == 0) && search == "") { var data1 = _context.workOrders.AsSplitQuery().Where(w => w.istemplate != true).Include(w => w.Locations).Include(w => w.AssignToUser).AsNoTracking().AsQueryable(); return data1; } var currentDate = DateTime.UtcNow.Date; var data = _context.workOrders.AsSplitQuery().Include(w => w.Locations).Include(w => w.AssignToUser) .Where(w => w.istemplate != true && ((w.WorkerOrderTitle.ToLower().Contains(search.ToLower()) || w.WorkerOrderNumber.ToLower().Contains(search.ToLower()) || w.Locations.Title.ToLower().Contains(search.ToLower())) && (assignto.Count() == 0 || assignto.Contains(w.AssignTo)) && (location.Count() == 0 || (w.LocationId.HasValue && location.Contains(w.LocationId.Value))) && (priority.Count() == 0 || priority.Contains(w.Priority)) && ((status.Count() == 0 || status.Contains(w.Status)) ))) .AsNoTracking().AsQueryable(); // Perform client-side filtering for due dates data = data.Where(w => duedate.Count() == 0 || duedate.Any(dd => w.DueDate.HasValue && CheckDueDate(dd, w.DueDate.Value.Date, currentDate))) .AsQueryable(); // Apply sorting // Apply sorting if (!string.IsNullOrEmpty(sort) && !string.IsNullOrEmpty(sortby) && sortby != "") { switch (sortby) { case "Name": data = (sort.ToLower() == "ascending") ? data.OrderBy(w => w.WorkerOrderTitle).AsQueryable() : data.OrderByDescending(w => w.WorkerOrderTitle).AsQueryable(); break; case "Due Date": data = (sort.ToLower() == "ascending") ? data.OrderBy(w => w.DueDate).AsQueryable() : data.OrderByDescending(w => w.DueDate).AsQueryable(); break; case "Severity": data = (sort.ToLower() == "ascending") ? data.OrderBy(w => w.Priority).AsQueryable() : data.OrderByDescending(w => w.Priority).AsQueryable(); break; default: // Handle default case or throw an exception break; } } return data; } catch (Exception ex) { var data1 = _context.workOrders.AsSplitQuery().Where(w => w.istemplate != true).Include(w => w.Locations).Include(w => w.AssignToUser).AsNoTracking().AsQueryable(); return data1; } } public async Task GetworkorderReport() { _context.ChangeTracker.Clear(); // Use ChangeTracker.Clear() instead of setting EntityState.Detached var data = new Workordervm { CreatedWorkorder = await _context.workOrders.CountAsync(w => w.istemplate != true), CompletedWorkorder = await _context.workOrders.CountAsync(w => w.istemplate != true && w.Status == "Done"), Severity1 = await _context.workOrders.CountAsync(w => w.istemplate != true && w.Priority == "Sev 1"), Severity2 = await _context.workOrders.CountAsync(w => w.istemplate != true && w.Priority == "Sev 2"), Severity3 = await _context.workOrders.CountAsync(w => w.istemplate != true && w.Priority == "Sev 3"), Severity4 = await _context.workOrders.CountAsync(w => w.istemplate != true && w.Priority == "Sev 4"), Severity5 = await _context.workOrders.CountAsync(w => w.istemplate != true && w.Priority == "Sev 5"), }; return data; } bool CheckDueDate(string dd, DateTime dueDate, DateTime currentDate) { return dd switch { "Today" => dueDate == currentDate, "Tomorrow" => dueDate == currentDate.AddDays(1), "Next Week" => dueDate >= currentDate.AddDays(1) && dueDate <= currentDate.AddDays(7), "Next Month" => dueDate >= currentDate.AddDays(1) && dueDate <= currentDate.AddMonths(1), "Over Due" => dueDate < currentDate, _ => false }; } public async Task Addworkorder(WorkOrder model, List files) { _sunsetGuard.ThrowIfMutationsBlocked(); try { _context.ChangeTracker.Clear(); var workordercategories = model.WorkOrderCategories; var exist = _context.workOrders.Include(i => i.WorkOrderCategories).Include(i => i.WorkOrderContacts).Where(w => w.Id == model.Id).FirstOrDefault(); model.workOrderAttachments = model.workOrderAttachments == null ? new List() : model.workOrderAttachments; if (exist == null) { if (files != null && files.Count > 0) { foreach (var file in files) { if (file.file != null) { var result = await _uploadFileHelper.UploadFiles(file.file, null); if (result.StatusCode == 200) { if (file.Name == "attachment1") { // model.Attachments = result.Domain; model.workOrderAttachments.Add(new WorkOrderAttachments { Attachments = result.Domain }); } else if (file.Name == "attachment2") { model.BeforPhotoAttachment = result.Domain; } else if (file.Name == "attachment3") { model.AfterPhotoAttachment = result.Domain; } else if (file.Name == "attachment4") { model.SignOffAttachment = result.Domain; } } else { return result.Message; } } } } //model.WorkOrderContacts = model.WorkOrderContacts == null ? new List() : model.WorkOrderContacts; //foreach (var itm in model.WorkOrderContacts) //{ // model.WorkOrderContacts.Add(new WorkOrderContacts { ContactId = itm.ContactId }); //} //exist.WorkOrderCategories = exist.WorkOrderCategories == null ? new List() : exist.WorkOrderCategories; //foreach (var itm in model.WorkOrderCategories) //{ // exist.WorkOrderCategories.Add(new WorkOrderCategories { CategoryId = itm.CategoryId }); //} model.Status = "Open"; model.AssignToUser = null; model.Locations = null; _context.workOrders.Add(model); } else { exist.workOrderAttachments = exist.workOrderAttachments == null ? new List() : exist.workOrderAttachments; exist.PO = model.PO; exist.WorkerOrderNumber = model.WorkerOrderNumber; exist.WorkerOrderTitle = model.WorkerOrderTitle; exist.Description = model.Description; //exist.POC = model.POC; exist.TT = model.TT; exist.AssignTo = model.AssignTo; exist.DueDate = model.DueDate; exist.Priority = model.Priority; //exist.CategoryId = model.CategoryId; exist.LocationId = model.LocationId; // if (exist.WorkOrderCategories != null) { if (exist.WorkOrderCategories.Count > 0) { _context.RemoveRange(exist.WorkOrderCategories.ToList()); } } if (exist.WorkOrderContacts != null) { if (exist.WorkOrderContacts.Count > 0) { _context.RemoveRange(exist.WorkOrderContacts.ToList()); } } exist.WorkOrderContacts = exist.WorkOrderContacts == null ? new List() : exist.WorkOrderContacts; foreach (var itm in model.WorkOrderContacts) { exist.WorkOrderContacts.Add(new WorkOrderContacts { ContactId = itm.ContactId }); } exist.WorkOrderCategories = exist.WorkOrderCategories == null ? new List() : exist.WorkOrderCategories; foreach (var itm in model.WorkOrderCategories) { exist.WorkOrderCategories.Add(new WorkOrderCategories { CategoryId = itm.CategoryId }); } exist.BeforPhotoIssue = model.BeforPhotoIssue; exist.AfterPhotoIssue = model.AfterPhotoIssue; exist.SignOffName = model.SignOffName; exist.SignOffSignature = model.SignOffSignature; if (files != null && files.Count > 0) { foreach (var file in files) { if (file.Name == "attachment1") { var result = await _uploadFileHelper.UploadFiles(file.file, exist.Attachments); if (result.StatusCode == 200) { // model.Attachments = result.Domain; exist.workOrderAttachments.Add(new WorkOrderAttachments { Attachments = result.Domain }); } } else if (file.Name == "attachment2") { var result = await _uploadFileHelper.UploadFiles(file.file, exist.BeforPhotoAttachment); if (result.StatusCode == 200) { exist.BeforPhotoAttachment = result.Domain; } } else if (file.Name == "attachment3") { var result = await _uploadFileHelper.UploadFiles(file.file, exist.AfterPhotoAttachment); if (result.StatusCode == 200) { exist.AfterPhotoAttachment = result.Domain; } } else if (file.Name == "attachment4") { var result = await _uploadFileHelper.UploadFiles(file.file, exist.SignOffAttachment); if (result.StatusCode == 200) { exist.SignOffAttachment = result.Domain; } } } } _context.Update(exist); } await _context.SaveChangesAsync(); return "success"; } catch (Exception ex) { return ex.Message ?? ""; } } public async Task AddWorkOrderAsTemplate(WorkOrder model1, List files) { try { Template model = new Template { WorkerOrderNumber = model1.WorkerOrderNumber, WorkerOrderTitle = model1.WorkerOrderTitle, Description = model1.Description, PO = model1.PO, TT = model1.TT, // POC = model1.POC, AssignTo = model1.AssignTo, DueDate = model1.DueDate, Priority = model1.Priority, LocationId = model1.LocationId, // CategoryId = model1.CategoryId, BeforPhotoIssue = model1.BeforPhotoIssue, AfterPhotoIssue = model1.AfterPhotoIssue, SignOffName = model1.SignOffName, SignOffSignature = model1.SignOffSignature, Attachments = model1.Attachments, BeforPhotoAttachment = model1.BeforPhotoAttachment, AfterPhotoAttachment = model1.AfterPhotoAttachment, SignOffAttachment = model1.SignOffAttachment, Status = model1.Status }; _context.Entry(model1).State = EntityState.Detached; // Handle file uploads if (files != null && files.Count > 0) { foreach (var file in files) { if (file.file != null) { var result = await _uploadFileHelper.UploadFiles(file.file, null); if (result.StatusCode == 200) { // Set file-related properties switch (file.Name) { case "attachment1": model.Attachments = result.Domain; break; case "attachment2": model.BeforPhotoAttachment = result.Domain; break; case "attachment3": model.AfterPhotoAttachment = result.Domain; break; case "attachment4": model.SignOffAttachment = result.Domain; break; } } else { return result.Message; } } } } _context.Templates.Add(model); _context.SaveChanges(); return "success"; } catch (Exception ex) { return ex.Message ?? ""; } } public async Task Copyworkorder(int id) { try { var exist = _context.workOrders.Where(w => w.Id == id).FirstOrDefault(); await _context.SaveChangesAsync(); return "success"; } catch (Exception ex) { return ex.Message; } } public async Task Deleteworkorder(int id) { _sunsetGuard.ThrowIfMutationsBlocked(); _context.ChangeTracker.Clear(); try { var exist = _context.workOrders.Where(w => w.Id == id).FirstOrDefault(); if (exist != null) { var quotes = _context.Quotes.Where(w => w.WorkorderId == id).ToList(); if (quotes.Count() > 0) { foreach (var itm in quotes) { var existquotes = _context.Quotes.Where(w => w.Id == itm.Id).FirstOrDefault(); existquotes.WorkorderId = null; } } var attachments = _context.workOrderAttachments.Where(w => w.WorkorderId == id).ToList(); if (attachments.Count() > 0) { _context.RemoveRange(attachments); } var contacts = _context.WorkOrderContacts.Where(w => w.WorkorderId == id).ToList(); if (contacts.Count() > 0) { _context.RemoveRange(contacts); } var category = _context.workOrderCategories.Where(w => w.WorkorderId == id).ToList(); if (category.Count() > 0) { _context.RemoveRange(category); } var comments = _context.Comments.Where(w => w.WorkerOrderId == id).ToList(); if (comments.Count() > 0) { _context.RemoveRange(comments); } _context.Remove(exist); } await _context.SaveChangesAsync(); return "success"; } catch (Exception ex) { return ex.Message; } } public async Task GetworkorderById(int Id) { var data = await _context.workOrders.Include(i => i.Quotes).Include(f => f.WorkOrderContacts).ThenInclude(i => i.POC).Include(f => f.workOrderAttachments).Include(f => f.Locations).Include(f => f.WorkOrderCategories).ThenInclude(i => i.Category).Include(f => f.AssignToUser).Where(w => w.Id == Id).FirstOrDefaultAsync(); return data ?? new WorkOrder(); } public async Task ChangeStatus(int id, string status) { _context.ChangeTracker.Clear(); try { var data = await _context.workOrders.Where(w => w.Id == id).FirstOrDefaultAsync(); data.Status = status; _context.Update(data); await _context.SaveChangesAsync(); _context.ChangeTracker.Clear(); return "success"; } catch (Exception ex) { return ex.Message; } } public async Task AddComment(Comments model, IBrowserFile file) { try { var userId = _httpContextAccessor?.HttpContext?.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value ?? ""; var exist = await _context.Comments.Where(w => w.Id == model.Id).FirstOrDefaultAsync(); if (exist != null) { exist.CreatedDate = model.CreatedDate; exist.WorkerOrderId = model.WorkerOrderId; exist.Commenttext = model.Commenttext; exist.UserId = userId; } else { if (file != null) { var result = await _uploadFileHelper.UploadFiles(file, null); if (result.StatusCode == 200) { model.Documents = result.Domain; } else { return result.Message; } } model.CreatedDate = DateTime.Now; model.UserId = userId; _context.Comments.Add(model); } await _context.SaveChangesAsync(); return "success"; } catch (Exception ex) { return ex.Message; } } public async Task SendEmailWorrkorder(byte[] pdfBytes, int Id) { try { var user = _context.Users.Where(w => w.WorkOrders.Where(w => w.Id == Id).Any()).FirstOrDefault(); if (user != null) { var subject = "Work Order"; var response = await _sendemail.SendEMailAttachment(user.Email ?? "", subject, pdfBytes); if (response) { return "success"; } else { return "Some thing went wrong"; } } return "Email Not Found"; } catch (Exception ex) { return ex.Message; } } public async Task> GetComments(int id) { var list = await _context.Comments.Where(w => w.WorkerOrderId == id).Include(i => i.ApplicationUser).ToListAsync(); return list; } #region dropdowns of work order public async Task> GetUsers() { var filteredUsers = await (from user in _context.Users where !(from userRole in _context.UserRoles join role in _context.Roles on userRole.RoleId equals role.Id where role.Name == "Admin" || role.Name == "Manager" select userRole.UserId).Contains(user.Id) select user).ToListAsync(); return filteredUsers; } public async Task> GetLocationsVM() { var data = await _context.Locations.Select(s => new LocationViewModel { Id = s.Id, Name = s.Title + " - " + s.Name }).ToListAsync(); return data; } public async Task> GetLocations() { var data = await _context.Locations.ToListAsync(); return data; } public async Task> GetCategories() { var data = await _context.Categories.ToListAsync(); return data; } public async Task> GetContacts() { var data = await _context.Contacts.ToListAsync(); return data; } #endregion } }