using AutoMapper; using DocumentFormat.OpenXml.Office.CustomUI; using DocumentFormat.OpenXml.Office2010.Excel; using DocumentFormat.OpenXml.Spreadsheet; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.EntityFrameworkCore; using Serilog; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using WorkFlowCheck.BL.DocumentGenerator; using WorkFlowCheck.BL.Services.Interfaces; using WorkFlowCheck.Common.DTO; using WorkFlowCheck.Common.Enums; using WorkFlowCheck.DL; using WorkFlowCheck.DL.Entities; namespace WorkFlowCheck.BL.Services { public class CheckListService : BaseService, ICheckListService { private readonly INumberGeneratorService _numberGeneratorService; private readonly IMessageService _messageService; public CheckListService(AppDbContext dbContext, IMapper mapper, INumberGeneratorService numberGeneratorService, IMessageService messageService, IUserService userService) : base(dbContext, mapper) { _numberGeneratorService = numberGeneratorService; _messageService = messageService; } public async Task GetCheckListHeaderAsync(int Id) { var retVal = new CheckListHeaderDTO() { CheckListRowDTO = new List() }; try { var res = await _dbContext.CheckListHeaders .Where(w => w.Id == Id) .Include(i => i.User) .Include(i => i.AcceptUser) .Include(i => i.CheckListRows) .ThenInclude(r => r.CheckListTemplateRow) .ThenInclude(r => r.CheckPoint) .Include(i => i.CheckListRows) .ThenInclude(r => r.CheckListTemplateRow) .ThenInclude(r => r.Equipment) .AsNoTracking() .FirstOrDefaultAsync(); if (res != null) { res.CheckListRows = res.CheckListRows .OrderBy(r => r.CheckListTemplateRow.CheckPoint?.ShortName ?? string.Empty) .ThenBy(r => r.CheckListTemplateRow.RowIndex) .ToList(); } if (res != null) { retVal = _mapper.Map(res); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task> GetAllCheckListHeaderAsync() { var retVal = new List(); try { var checkListHeaders = await _dbContext.CheckListHeaders .Include(i => i.CheckListRows) .Include(i => i.User) .Include(i => i.AcceptUser) .AsNoTracking() .ToListAsync(); if (checkListHeaders != null) { retVal = _mapper.Map>(checkListHeaders); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task UpdateCheckListHeaderAsync(CheckListHeaderDTO checkListHeaderDTO) { var retVal = new CheckListHeaderDTO() { CheckListRowDTO = new List() }; try { if (checkListHeaderDTO.Id == 0) { var checkListHeader = new CheckListHeader() { CheckListTemplateHeaderId = checkListHeaderDTO.CheckListTemplateHeaderDTO.Id, Description = checkListHeaderDTO.Description, ShortName = checkListHeaderDTO.ShortName, GuidNumber = Guid.NewGuid(), }; _dbContext.CheckListHeaders.Add(checkListHeader); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(checkListHeader); } else { var checkListHeader = await _dbContext.CheckListHeaders .Include(i => i.CheckListRows) .Where(w => w.Id == checkListHeaderDTO.Id) .FirstOrDefaultAsync(); if (checkListHeader != null) { checkListHeader.Description = checkListHeaderDTO.Description; checkListHeader.ShortName = checkListHeaderDTO.ShortName; await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(checkListHeader); } } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task StartNewCheckListAsync(CheckListHeaderNewDTO checkListHeaderNewDTO) { var retVal = new CheckListHeaderDTO() { CheckListRowDTO = new List() }; using var transaction = await _dbContext.Database.BeginTransactionAsync(); try { var checkListTemplateHeader = await _dbContext.CheckListTemplateHeaders .Where(w => w.Id == checkListHeaderNewDTO.CheckListTemplateHeaderId) .FirstOrDefaultAsync(); if (checkListTemplateHeader == null) { return retVal; } var currentDate = DateTime.UtcNow; var documentNumber = await _numberGeneratorService.GenerateNextNumberAsync(checkListTemplateHeader.NumberGenerator1Id ?? 1, transaction, currentDate); CheckListHeader checkListHeader = new CheckListHeader() { CheckListTemplateHeaderId = checkListHeaderNewDTO.CheckListTemplateHeaderId, CheckStatus = CheckStatus.Open, DateExecution = currentDate, IsEditable = true, UserId = checkListHeaderNewDTO.UserId, ShortName = "", Description = checkListTemplateHeader.Description ?? "", DocumentNumber = documentNumber, GuidNumber = Guid.NewGuid(), IsDeleted = false, IsStorno = false, CheckListRows = new List() }; _dbContext.CheckListHeaders.Add(checkListHeader); await _dbContext.SaveChangesAsync(); var checkListTemplateRows = await _dbContext.CheckListTemplateRows .Where(w => w.CheckListTemplateHeaderId == checkListHeaderNewDTO.CheckListTemplateHeaderId) .OrderBy(o => o.RowIndex) .ToListAsync(); foreach (var item in checkListTemplateRows) { CheckListRow checkListRow = new CheckListRow() { Answer = "", CheckListHeaderId = checkListHeader.Id, CheckListTemplateRowId = item.Id, GuidNumber = Guid.NewGuid(), IsDeleted = false, PhotoFileName = "", }; _dbContext.CheckListRows.Add(checkListRow); } await _dbContext.SaveChangesAsync(); await transaction.CommitAsync(); retVal = _mapper.Map(checkListHeader); } catch (Exception ex) { await transaction.RollbackAsync(); Log.Error(ex.Message); } return retVal; } public async Task AcceptCheckListHeaderAsync(int id, int userid) { var retVal = false; try { var user = await _dbContext.Users .Where(w => w.Id == userid) .FirstOrDefaultAsync(); if (user == null) return false; var checkListHeader = await _dbContext.CheckListHeaders .Where(w => w.Id == id && w.CheckStatus == CheckStatus.Sent) .FirstOrDefaultAsync(); if (checkListHeader != null) { checkListHeader.CheckStatus = CheckStatus.Signed; checkListHeader.IsEditable = false; checkListHeader.AcceptUserId = userid; checkListHeader.DateExecution = DateTime.Now; Log.ForContext("TAG", "BusinessFlow").Warning($"Ellenőrzési lap státuszváltozása, jóváhagyás: Ellenőrzés:{checkListHeader.DocumentNumber}, Felhasználó: {user.LastName} {user.FirstName}"); await _dbContext.SaveChangesAsync(); var pdf = await CreateCheckListHeaderPDFAsync(id); if (pdf != null && pdf.Length > 0) { string pdfDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Pdf"); var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss"); var fileName = $"CD_{timestamp}_{checkListHeader.GuidNumber.ToString().ToUpper()}.pdf"; var filePath = Path.Combine(pdfDirectory, fileName); await File.WriteAllBytesAsync(filePath, pdf); await SendMailToAcceptedUser(filePath, checkListHeader, userid); retVal = true; } } } catch (Exception ex) { retVal = false; Log.Error(ex.Message); } return retVal; } private async Task SendMailToAcceptedUser(string filePath, CheckListHeader checkListHeader, int userId) { try { var user = _dbContext.Users.Where(W => W.Id == userId).FirstOrDefault(); if (user != null) { if (!string.IsNullOrEmpty(user.Email)) { var recepients = new List() { user.Email, }; await _messageService.SendMailAsync(recepients, $"Értesítés folyamat jóváhagyásáról {checkListHeader.DocumentNumber}", GetAcceptCheckListHeaderMessageBody(checkListHeader), filePath); } } } catch (Exception ex) { } } private string GetAcceptCheckListHeaderMessageBody(CheckListHeader checkListHeader) { var assembly = Assembly.GetExecutingAssembly(); var resourceName = "WorkFlowCheck.BL.HtmlTemplates.AcceptCheckListHeaderBody.html"; using var stream = assembly.GetManifestResourceStream(resourceName); if (stream == null) throw new FileNotFoundException($"Nem található a beágyazott erőforrás: {resourceName}"); using var reader = new StreamReader(stream); var html = reader.ReadToEnd(); return html.Replace("#DocumentNumber#", checkListHeader.DocumentNumber); } public async Task CreateCheckListHeaderPDFAsync(int checkListHeaderId) { try { var checkListHeader = await this.GetCheckListHeaderAsync(checkListHeaderId); string pdfDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Pdf"); byte[] byteArray = File.ReadAllBytes(Path.Combine(pdfDirectory, "CheckList_Template_V1.docx")); SablonGenerator gen = new SablonGenerator(byteArray); gen.SimpleReplace("#description#", checkListHeader.Description); gen.SimpleReplace("#DocumentNumber#", checkListHeader.DocumentNumber); gen.SimpleReplace("#DateExecution#", checkListHeader.DateExecution.ToString("yyyy.MM.dd HH:mm")); gen.SimpleReplace("#WorkUser#", $"{checkListHeader.UserDTO?.LastName} {checkListHeader.UserDTO?.FirstName}"); gen.SimpleReplace("#AcceptUser#", $"{checkListHeader.AcceptUserDTO?.LastName} {checkListHeader.AcceptUserDTO?.FirstName}"); gen.SimpleReplace("#Guid#", checkListHeader.GuidNumber.ToString()); if (checkListHeader.CheckListRowDTO != null && checkListHeader.CheckListRowDTO.Count > 0) { var elements = new List>(); foreach (var item in checkListHeader.CheckListRowDTO) { if (item.CheckListTemplateRowDTO != null) { var cells = new List { $"{item.CheckListTemplateRowDTO.RowIndex.ToString()}.", item.CheckListTemplateRowDTO.OperationDescription, item.Answer }; elements.Add(cells); } } gen.SetTable(elements, "#rowindex"); } byte[] content = gen.CloseAndGetDocument(); string imageDirectory = Path.Combine(Directory.GetCurrentDirectory(), "Images"); var images = checkListHeader.CheckListRowDTO.Where(w => (w.CheckListTemplateRowDTO.AnswerType == "P" || w.CheckListTemplateRowDTO.AnswerType == "PN") && string.IsNullOrEmpty(w.Answer) != true) .Select(s => Path.Combine(imageDirectory, s.Answer)) .ToList(); return DokumentumGenerator.DocxToPdfL(content, images); } catch (Exception ex) { Log.Error(ex.Message); } return new byte[0]; } public async Task BlockCheckListHeaderAsync(int id, int userid) { var retVal = false; try { var checkListHeader = await _dbContext.CheckListHeaders .Where(w => w.Id == id && w.CheckStatus == CheckStatus.InProgress) .FirstOrDefaultAsync(); if (checkListHeader != null && checkListHeader.CheckStatus == CheckStatus.InProgress) { checkListHeader.CheckStatus = CheckStatus.Blocked; checkListHeader.IsEditable = false; Log.ForContext("TAG", "BusinessFlow").Warning($"Ellenőrzési lap blokkolva: Ellenőrzés:{id}, Felhasználó:{userid}"); await _dbContext.SaveChangesAsync(); retVal = true; } } catch (Exception ex) { retVal = false; Log.Error(ex.Message); } return retVal; } public async Task UnBlockCheckListHeaderAsync(int id, int userid) { var retVal = false; try { var checkListHeader = await _dbContext.CheckListHeaders .Where(w => w.Id == id && w.CheckStatus == CheckStatus.Blocked) .FirstOrDefaultAsync(); if (checkListHeader != null && checkListHeader.CheckStatus == CheckStatus.Blocked) { checkListHeader.CheckStatus = CheckStatus.InProgress; checkListHeader.IsEditable = true; Log.ForContext("TAG", "BusinessFlow").Warning($"Ellenőrzési lap feloldva: Ellenőrzés:{id}, Felhasználó:{userid}"); await _dbContext.SaveChangesAsync(); retVal = true; } } catch (Exception ex) { retVal = false; Log.Error(ex.Message); } return retVal; } public async Task CloseCheckListHeader(CheckListHeaderCloseDTO closeCheckListHeaderCloseDTO) { var retVal = false; try { var checkListHeader = await _dbContext.CheckListHeaders .Where(w => w.Id == closeCheckListHeaderCloseDTO.Id && (w.CheckStatus == CheckStatus.Blocked || w.CheckStatus == CheckStatus.InProgress || w.CheckStatus == CheckStatus.Open )) .FirstOrDefaultAsync(); if (checkListHeader != null) { checkListHeader.CheckStatus = CheckStatus.Closed; checkListHeader.IsEditable = false; checkListHeader.AcceptUserId = closeCheckListHeaderCloseDTO.UserId; Log.ForContext("TAG", "BusinessFlow").Warning($"Ellenőrzési lap lezárva: Ellenőrzés:{closeCheckListHeaderCloseDTO.Id}, " + $"Felhasználó:{closeCheckListHeaderCloseDTO.UserId}, " + $"Lezárás oka: {closeCheckListHeaderCloseDTO.CloseReason}"); await _dbContext.SaveChangesAsync(); retVal = true; } } catch (Exception ex) { retVal = false; Log.Error(ex.Message); } return retVal; } public async Task GetCheckListTemplateHeaderAsync(int Id) { var retVal = new CheckListTemplateHeaderDTO() { CheckListTemplateRowDTO = new List() }; try { var res = await _dbContext.CheckListTemplateHeaders .Where(w => w.Id == Id) .Include(i => i.CheckListTemplateRows) .ThenInclude(i => i.CheckPoint) .Include(i => i.CheckListTemplateRows) .ThenInclude(i => i.Equipment) .AsNoTracking() .FirstOrDefaultAsync(); if (res != null) { retVal = _mapper.Map(res); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task> GetAllCheckListTemplateHeaderAsync() { var retVal = new List(); try { var roles = await _dbContext.CheckListTemplateHeaders .Include(i => i.CheckListTemplateRows) .AsNoTracking() .ToListAsync(); if (roles != null) { retVal = _mapper.Map>(roles); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task UpdateCheckListTemplateHeaderAsync(CheckListTemplateHeaderDTO checkListTemplateHeaderDTO) { var retVal = new CheckListTemplateHeaderDTO() { CheckListTemplateRowDTO = new List() }; try { if (checkListTemplateHeaderDTO.Id == 0) { var checkListTemplateHeader = new CheckListTemplateHeader() { Description = checkListTemplateHeaderDTO.Description, ShortName = checkListTemplateHeaderDTO.ShortName, IsDeleted = false, NumberGenerator1Id = checkListTemplateHeaderDTO.NumberGenerator1Id, NumberGenerator2Id = checkListTemplateHeaderDTO.NumberGenerator2Id, }; _dbContext.CheckListTemplateHeaders.Add(checkListTemplateHeader); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(checkListTemplateHeader); } else { var checkListTemplateHeader = await _dbContext.CheckListTemplateHeaders .Include(i => i.CheckListTemplateRows) .Where(w => w.Id == checkListTemplateHeaderDTO.Id) .FirstOrDefaultAsync(); if (checkListTemplateHeader != null) { checkListTemplateHeader.Description = checkListTemplateHeaderDTO.Description; checkListTemplateHeader.ShortName = checkListTemplateHeaderDTO.ShortName; await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(checkListTemplateHeader); } } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task DeleteCheckListTemplateHeaderAsync(int id) { return await DeleteEntityByIdAsync(id); } public async Task CloneCheckListTemplateHeaderAsync(int id) { var retVal = false; try { var checkListTemplateHeader = await _dbContext.CheckListTemplateHeaders .AsNoTracking() .Include(i => i.CheckListTemplateRows) .Where(w => w.Id == id).FirstOrDefaultAsync(); if (checkListTemplateHeader != null) { var newCheckListTemplateHeader = new CheckListTemplateHeader() { CheckListTemplateRows = new List(), Description = checkListTemplateHeader.Description, IsDeleted = false, NumberGenerator1Id = checkListTemplateHeader.NumberGenerator1Id, NumberGenerator2Id = checkListTemplateHeader.NumberGenerator2Id, ShortName = $"{checkListTemplateHeader.ShortName} (másolat)", }; foreach (var checkListTemplateRow in checkListTemplateHeader.CheckListTemplateRows) { var newCheckListTemplateRow = new CheckListTemplateRow() { AnswerType = checkListTemplateRow.AnswerType, CheckListTemplateHeader = newCheckListTemplateHeader, CheckPointId = checkListTemplateRow.CheckPointId, EquipmentId = checkListTemplateRow.EquipmentId, IsDeleted = false, OperationDescription = checkListTemplateRow.OperationDescription, RowIndex = checkListTemplateRow.RowIndex, }; newCheckListTemplateHeader.CheckListTemplateRows.Add(newCheckListTemplateRow); } _dbContext.CheckListTemplateHeaders.Add(newCheckListTemplateHeader); await _dbContext.SaveChangesAsync(); } } catch (Exception ex) { retVal = false; Log.ForContext("TAG", "BusinessFlow").Error(ex.Message); } return retVal; } public async Task GetCheckListTemplateRowAsync(int id) { var retVal = new CheckListTemplateRowDTO(); try { var res = await _dbContext.CheckListTemplateRows .Include(i => i.Equipment) .Include(i => i.CheckPoint) .Where(w => w.Id == id) .AsNoTracking() .FirstOrDefaultAsync(); if (res != null) { retVal = _mapper.Map(res); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task DeleteCheckListTemplateRowAsync(int id) { return await DeleteEntityByIdAsync(id); } public async Task UpdateCheckListTemplateRowAsync(CheckListTemplateRowDTO checkListTemplateRowDTO) { var retVal = new CheckListTemplateRowDTO() { }; try { if (checkListTemplateRowDTO.Id == 0) { var checkListTemplateRow = new CheckListTemplateRow() { CheckListTemplateHeaderId = checkListTemplateRowDTO.CheckListTemplateHeaderId, CheckPointId = checkListTemplateRowDTO.CheckPointId, EquipmentId = checkListTemplateRowDTO.EquipmentId, OperationDescription = checkListTemplateRowDTO.OperationDescription, AnswerType = checkListTemplateRowDTO.AnswerType, RowIndex = checkListTemplateRowDTO.RowIndex, }; _dbContext.CheckListTemplateRows.Add(checkListTemplateRow); await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(checkListTemplateRow); } else { var checkListTemplateRow = await _dbContext.CheckListTemplateRows .Where(w => w.Id == checkListTemplateRowDTO.Id) .FirstOrDefaultAsync(); if (checkListTemplateRow != null) { checkListTemplateRow.CheckListTemplateHeaderId = checkListTemplateRowDTO.CheckListTemplateHeaderId; checkListTemplateRow.CheckPointId = checkListTemplateRowDTO.CheckPointId; checkListTemplateRow.EquipmentId = checkListTemplateRowDTO.EquipmentId; checkListTemplateRow.OperationDescription = checkListTemplateRowDTO.OperationDescription; checkListTemplateRow.AnswerType = checkListTemplateRowDTO.AnswerType; checkListTemplateRow.RowIndex = checkListTemplateRowDTO.RowIndex; await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(checkListTemplateRow); } } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task GetCheckListRowAsync(int id) { var retVal = new CheckListRowDTO(); try { var res = await _dbContext.CheckListRows .Include(i => i.CheckListTemplateRow) .Where(w => w.Id == id) .AsNoTracking() .FirstOrDefaultAsync(); if (res != null) { retVal = _mapper.Map(res); } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } public async Task UpdateCheckListRowAsync(CheckListRowDTO checkListRowDTO) { var retVal = new CheckListRowDTO() { }; try { if (checkListRowDTO.Id == 0) { } else { var checkListRow = await _dbContext.CheckListRows .Where(w => w.Id == checkListRowDTO.Id) .FirstOrDefaultAsync(); if (checkListRow != null) { checkListRow.Answer = checkListRowDTO.Answer; //checkListRow.Photo = checkListRowDTO.Photo; await _dbContext.SaveChangesAsync(); retVal = _mapper.Map(checkListRow); } } } catch (Exception ex) { Log.Error(ex.Message); } return retVal; } } }