using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Text; using FMSAdmin.Data; using FMSAdmin.Helpers; using FMSAdmin.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using FMSAdmin.Models; using System.Transactions; using FMSApp.Repositories; namespace FMSApp.Services { public class WorkRequestService { private readonly ILogger _logger; private readonly FMSContext _context; private readonly AppSettings _appSettings; private readonly StorageHelper _storage; private readonly WorkRequestRepository _workRequestRepository; private readonly WorkConfigRepository _workConfigRepository; public WorkRequestService( ILogger logger, FMSContext context, IOptions appSettings, StorageHelper storage, WorkRequestRepository workRequestRepository, WorkConfigRepository workConfigRepository ) { _logger = logger; _context = context; _appSettings = appSettings.Value; _storage = storage; _workRequestRepository = workRequestRepository; _workConfigRepository = workConfigRepository; } /// /// 저장(작업이력추가 이전까지 수정가능) /// 신규프로세스 / Schedule미사용 /// Schedule 미사용시 계획에 대한 모든 작업이 한번에 일괄등록된다. /// 일괄등록된 데이터가 작업지시돼고, 작업진행이 됐을때... 작업진행 화면에서 수정이 가능해 져야한다. /// 그래서, 작업계획, 작업대기, 작업진행 상태의 데이터 모두 수정가능해야 한다. /// /// /// public void SaveBeforeAddHistory(FmsWorkRequest data) { using (var trans = new TransactionScope()) { var persist = _context.FmsWorkRequest.FirstOrDefault( x => x.SiteId == data.SiteId && x.WorkRequestId == data.WorkRequestId ); if (persist == null) { if (data.WorkTypeId == 0) { throw new ServiceException("업무구분이 입력되지 않았습니다."); } var detailType = _context.FmsWorkCodeDetailType.FirstOrDefault(x => x.WorkDetailTypeId == data.WorkDetailTypeId); if (data.WorkTypeId == 5 || data.WorkTypeId == 6) { if (detailType == null) { throw new ServiceException("작업구분이 입력되지 않았습니다."); } } // 설비 기본정보 생성되지 않도록 처리 foreach (var facility in data.FmsWorkRequestToFacility) { facility.CmFacility = null; } // 사고가 아닐때 사고목록 초기화 if (Util.V(detailType, x => x.Code) != "ACCIDENT") { data.FmsWorkRequestToAccident = new List(); } // 사고 기본정보 생성되지 않도록 처리 foreach (var accident in data.FmsWorkRequestToAccident) { accident.FmsAccident = null; } // 민원이 아닐때 민원목록 초기화 if (Util.V(detailType, x => x.Code) != "COMPLAINT") { data.FmsWorkRequestToComplaint = new List(); } // 민원 기본정보 생성되지 않도록 처리 foreach (var complaint in data.FmsWorkRequestToComplaint) { complaint.FmsComplaints = null; } if (data.CmFile != null && data.CmFile.IsUpload) { data.CmFile.SiteId = data.SiteId; var category = _context.CmFileCategory.First(x => x.Name == "workrequest"); data.CmFile.FileCategory = category; data.CmFile.CreatedDate = DateTime.Now; } else { data.CmFile = null; } data.WorkProgressId = 1; data.WorkScheduleId = null; data.FmsWorkSchedule = null; data.RequestDate = DateTime.Now; _context.FmsWorkRequest.Add(data); _context.SaveChanges(); if (data.CmFile != null && data.CmFile.IsUpload) { _storage.CopyEntity(data.CmFile.Path, data.CmFile); } } else { if (_workConfigRepository.IsAutoResult(true)) { // 자동지시, 자동실행 일 경우 // 작업이력이 등록된 데이터를 진행중으로 본다. if (persist.FmsWorkResult != null && persist.FmsWorkResult.FmsWorkResultCheckItem != null && persist.FmsWorkResult.FmsWorkResultCheckItem.Count > 0) { throw new ServiceException("진행중인 작업은 계획 변경이 불가능합니다."); } } else if (_workConfigRepository.IsAutoOrder(true)) { // 자동지시일 경우 // 작업계획, 작업대기의 데이터만 변경가능하다. if (persist.WorkProgressId != 1 && persist.WorkProgressId != 3) { throw new ServiceException("진행중인 작업은 계획 변경이 불가능합니다."); } } else { // 그외 // 작업계획일때만 변경가능하다. if (persist.WorkProgressId != 1) { throw new ServiceException("진행중인 작업은 계획 변경이 불가능합니다."); } } // 작업계획의 일자 변경 if (persist.FmsWorkSchedule != null && Util.V(persist, x => x.FmsWorkSchedule.WorkDueDate.Date) != Util.V(data, x => x.StartWorkDate.Date)) { persist.FmsWorkSchedule.WorkDueDate = data.StartWorkDate.Date; } // 파일 Entity 처리 if (data.CmFile != null && data.CmFile.IsDelete) { persist.CmFile = null; persist.FileId = null; } else if (data.CmFile != null && data.CmFile.IsUpload) { var category = _context.CmFileCategory.First(x => x.Name == "workrequest"); persist.CmFile = new CmFile { SiteId = data.SiteId, FileCategory = category, CreatedDate = DateTime.Now, Name = data.CmFile.Name, FileSize = data.CmFile.FileSize, ContentType = data.CmFile.ContentType, }; } // 입력 데이터 반영 persist.BusinessFieldId = data.BusinessFieldId; persist.StartWorkDate = data.StartWorkDate; persist.Title = data.Title; persist.Content = data.Content; persist.WorkDetailTypeId = data.WorkDetailTypeId; persist.WorkPartnerId = data.WorkPartnerId; persist.WorkPrice = data.WorkPrice; //persist.WorkItem = data.WorkItem; persist.WorkEndDate = data.WorkEndDate; // 설비 전체 제거 persist.FmsWorkRequestToFacility.Clear(); // 추가된 설비 생성 foreach (var facility in data.FmsWorkRequestToFacility) { persist.FmsWorkRequestToFacility.Add(new FmsWorkRequestToFacility() { SiteId = persist.SiteId, WorkRequestId = persist.WorkRequestId, FacilityCode = facility.FacilityCode, }); } // 사고 전체 제거 persist.FmsWorkRequestToAccident.Clear(); // 추가된 사고 생성 foreach (var accident in data.FmsWorkRequestToAccident) { persist.FmsWorkRequestToAccident.Add(new FmsWorkRequestToAccident() { SiteId = persist.SiteId, WorkRequestId = persist.WorkRequestId, AccidentId = accident.AccidentId, }); } // 민원 전체 제거 persist.FmsWorkRequestToComplaint.Clear(); // 추가된 민원 생성 foreach (var complaint in data.FmsWorkRequestToComplaint) { persist.FmsWorkRequestToComplaint.Add(new FmsWorkRequestToComplaint() { SiteId = persist.SiteId, WorkRequestId = persist.WorkRequestId, ComplaintId = complaint.ComplaintId, }); } _context.FmsWorkRequest.Update(persist); _context.SaveChanges(); // FmsWorkOrder 업데이트 var order = persist.FmsWorkOrder; if (order != null) { order.BusinessFieldId = data.BusinessFieldId; order.StartWorkDate = data.StartWorkDate; order.Title = data.Title; order.Content = data.Content; order.FmsWorkOrderToFacility.Clear(); foreach (var facility in data.FmsWorkRequestToFacility) { order.FmsWorkOrderToFacility.Add(new FmsWorkOrderToFacility() { SiteId = persist.SiteId, WorkRequestId = persist.WorkRequestId, FacilityCode = facility.FacilityCode, }); } _context.FmsWorkOrder.Update(order); _context.SaveChanges(); } // FmsWorkResult 업데이트 var result = persist.FmsWorkResult; if (result != null) { result.StartDate = data.StartWorkDate.Date; result.EndDate = data.StartWorkDate.Date; result.FmsWorkResultToFacility.Clear(); foreach (var facility in data.FmsWorkRequestToFacility) { result.FmsWorkResultToFacility.Add(new FmsWorkResultToFacility() { SiteId = persist.SiteId, WorkRequestId = persist.WorkRequestId, FacilityCode = facility.FacilityCode, }); } _context.FmsWorkResult.Update(result); _context.SaveChanges(); } // 파일복사 if (data.CmFile != null && data.CmFile.IsUpload) { _storage.CopyEntity(data.CmFile.Path, persist.CmFile); if (persist.CmFile != null) { // 파일 삭제시 진짜 DB삭제? } } } // 자동지시 설정되어있을 경우 작업예정일이 오늘 포함 이전일자의 계획을 자동지시처리 if (_workConfigRepository.IsAutoOrder()) { persist = _context.FmsWorkRequest.FirstOrDefault( x => x.SiteId == data.SiteId && x.WorkRequestId == data.WorkRequestId ); if (persist.StartWorkDate.Date <= DateTime.Now.Date && persist.WorkProgressId == 1) { _workRequestRepository.WorkToOrder(persist.SiteId, persist.WorkRequestId, persist.RequestUserId, "", false); } } trans.Complete(); } } /// /// 민원 저장 /// /// /// public void SaveComplaints(FmsWorkRequest data) { using (var trans = new TransactionScope()) { var persist = _context.FmsWorkRequest.FirstOrDefault( x => x.SiteId == data.SiteId && x.WorkRequestId == data.WorkRequestId ); if (persist == null) throw new ServiceException("존재하지 않는 데이터입니다."); // 사고 전체 제거 persist.FmsWorkRequestToComplaint.Clear(); // 추가된 사고 생성 foreach (var complaint in data.FmsWorkRequestToComplaint) { persist.FmsWorkRequestToComplaint.Add(new FmsWorkRequestToComplaint() { SiteId = persist.SiteId, WorkRequestId = persist.WorkRequestId, ComplaintId = complaint.ComplaintId, }); } _context.FmsWorkRequest.Update(persist); _context.SaveChanges(); trans.Complete(); } } /// /// 사고 저장 /// /// /// public void SaveAccidents(FmsWorkRequest data) { using (var trans = new TransactionScope()) { var persist = _context.FmsWorkRequest.FirstOrDefault( x => x.SiteId == data.SiteId && x.WorkRequestId == data.WorkRequestId ); if (persist == null) throw new ServiceException("존재하지 않는 데이터입니다."); // 사고 전체 제거 persist.FmsWorkRequestToAccident.Clear(); // 추가된 사고 생성 foreach (var accident in data.FmsWorkRequestToAccident) { persist.FmsWorkRequestToAccident.Add(new FmsWorkRequestToAccident() { SiteId = persist.SiteId, WorkRequestId = persist.WorkRequestId, AccidentId = accident.AccidentId, }); } _context.FmsWorkRequest.Update(persist); _context.SaveChanges(); trans.Complete(); } } /// /// 저장 /// 기존프로세스 / Schedule사용 /// Schedule 사용시 Schedule 테이블의 데이터가 수정돼고 Schedule 당 하나의 Request 만 살아있으므로, /// 진행중인 Request 에 대해 수정이 가해질 필요가 없으므로 /// 기초계획등록 화면에서만 사용하며, 작업계획 상태의 데이터만 변경 가능하다. /// /// /// public void Save(FmsWorkRequest data) { using (var trans = new TransactionScope()) { var persist = _context.FmsWorkRequest.FirstOrDefault( x => x.SiteId == data.SiteId && x.WorkRequestId == data.WorkRequestId ); if (persist == null) { if (data.WorkTypeId == 0) { throw new ServiceException("업무구분이 입력되지 않았습니다."); } var detailType = _context.FmsWorkCodeDetailType.FirstOrDefault(x => x.WorkDetailTypeId == data.WorkDetailTypeId); if (data.WorkTypeId == 5 || data.WorkTypeId == 6) { if (detailType == null) { throw new ServiceException("작업구분이 입력되지 않았습니다."); } } // 설비 기본정보 생성되지 않도록 처리 foreach (var facility in data.FmsWorkRequestToFacility) { facility.CmFacility = null; } // 사고가 아닐때 사고목록 초기화 if (Util.V(detailType, x => x.Code) != "ACCIDENT") { data.FmsWorkRequestToAccident = new List(); } // 사고 기본정보 생성되지 않도록 처리 foreach (var accident in data.FmsWorkRequestToAccident) { accident.FmsAccident = null; } // 민원이 아닐때 민원목록 초기화 if (Util.V(detailType, x => x.Code) != "COMPLAINT") { data.FmsWorkRequestToComplaint = new List(); } // 민원 기본정보 생성되지 않도록 처리 foreach (var complaint in data.FmsWorkRequestToComplaint) { complaint.FmsComplaints = null; } data.WorkProgressId = 1; data.WorkScheduleId = null; data.FmsWorkSchedule = null; data.RequestDate = DateTime.Now; _context.FmsWorkRequest.Add(data); _context.SaveChanges(); } else { if (persist.WorkProgressId != 1) { throw new ServiceException("진행중인 작업은 계획 변경이 불가능합니다."); } // 작업계획의 일자 변경 if (persist.FmsWorkSchedule != null && Util.V(persist, x => x.FmsWorkSchedule.WorkDueDate.Date) != Util.V(data, x => x.StartWorkDate.Date)) { persist.FmsWorkSchedule.WorkDueDate = data.StartWorkDate.Date; } // 입력 데이터 반영 persist.BusinessFieldId = data.BusinessFieldId; persist.StartWorkDate = data.StartWorkDate; persist.Title = data.Title; persist.Content = data.Content; persist.WorkDetailTypeId = data.WorkDetailTypeId; persist.WorkPartnerName = data.WorkPartnerName; persist.WorkPrice = data.WorkPrice; //persist.WorkItem = data.WorkItem; // 설비 전체 제거 persist.FmsWorkRequestToFacility.Clear(); // 추가된 설비 생성 foreach (var facility in data.FmsWorkRequestToFacility) { persist.FmsWorkRequestToFacility.Add(new FmsWorkRequestToFacility() { SiteId = persist.SiteId, WorkRequestId = persist.WorkRequestId, FacilityCode = facility.FacilityCode, }); } // 사고 전체 제거 persist.FmsWorkRequestToAccident.Clear(); // 추가된 사고 생성 foreach (var accident in data.FmsWorkRequestToAccident) { persist.FmsWorkRequestToAccident.Add(new FmsWorkRequestToAccident() { SiteId = persist.SiteId, WorkRequestId = persist.WorkRequestId, AccidentId = accident.AccidentId, }); } // 민원 전체 제거 persist.FmsWorkRequestToComplaint.Clear(); // 추가된 민원 생성 foreach (var complaint in data.FmsWorkRequestToComplaint) { persist.FmsWorkRequestToComplaint.Add(new FmsWorkRequestToComplaint() { SiteId = persist.SiteId, WorkRequestId = persist.WorkRequestId, ComplaintId = complaint.ComplaintId, }); } _context.FmsWorkRequest.Update(persist); _context.SaveChanges(); } // 자동지시 설정되어있을 경우 작업예정일이 오늘 포함 이전일자의 계획을 자동지시처리 if (_workConfigRepository.IsAutoOrder()) { persist = _context.FmsWorkRequest.FirstOrDefault( x => x.SiteId == data.SiteId && x.WorkRequestId == data.WorkRequestId ); if (persist.StartWorkDate.Date <= DateTime.Now.Date) { _workRequestRepository.WorkToOrder(persist.SiteId, persist.WorkRequestId, persist.RequestUserId, "", false); } } trans.Complete(); } } public void Delete(int siteId, int workRequestId) { using (var trans = new TransactionScope()) { var workRequestToFacilities = _context.FmsWorkRequestToFacility.Where( x => x.SiteId == siteId && x.WorkRequestId == workRequestId ).ToList(); foreach (var item in workRequestToFacilities) { _context.FmsWorkRequestToFacility.Remove(item); } _context.SaveChanges(); var workRequestToAccidents = _context.FmsWorkRequestToAccident.Where( x => x.SiteId == siteId && x.WorkRequestId == workRequestId ).ToList(); foreach (var item in workRequestToAccidents) { _context.FmsWorkRequestToAccident.Remove(item); } _context.SaveChanges(); //민원 삭제 추가 var workRequestToComplaints = _context.FmsWorkRequestToComplaint.Where( x => x.SiteId == siteId && x.WorkRequestId == workRequestId ).ToList(); foreach (var item in workRequestToComplaints) { _context.FmsWorkRequestToComplaint.Remove(item); } _context.SaveChanges(); var workRequest = _context.FmsWorkRequest.Where( x => x.SiteId == siteId && x.WorkRequestId == workRequestId ).ToList(); foreach (var item in workRequest) { if (item.WorkScheduleId != null) { throw new ServiceException("정기점검, 법정검사는 삭제가 불가능합니다."); } if (item.WorkProgressId != 1) { throw new ServiceException("작업계획 단계의 데이터만 삭제 가능합니다."); } _context.FmsWorkRequest.Remove(item); } _context.SaveChanges(); trans.Complete(); } } // 반려 (실행계획 화면에서 빠지고 작업진행관리 화면에서 반려하도록 변경됨) public void Reject(FmsWorkRequest data, bool useSchedule, DateTime? confirmDate) { using (var trans = new TransactionScope()) { var persist = _context.FmsWorkRequest.FirstOrDefault( x => x.SiteId == data.SiteId && x.WorkRequestId == data.WorkRequestId ); if (persist == null) throw new ServiceException("존재하지 않는 데이터 입니다."); persist.WorkProgressId = 2; // 반려 persist.RejectUserId = data.RejectUserId; persist.RejectReason = data.RejectReason; persist.RejectDate = DateTime.Now; _context.FmsWorkRequest.Update(persist); _context.SaveChanges(); // 작업계획 처리 if (persist.WorkScheduleId != null && persist.WorkScheduleId != 0) { var schedule = _context.FmsWorkSchedule.FirstOrDefault( x => x.SiteId == data.SiteId && x.WorkScheduleId == persist.WorkScheduleId ); if (useSchedule) { if (confirmDate == null) throw new Exception("반복작업 반려시 확정일자는 필수입력사항입니다."); // 차기작업 확정일자 저장 schedule.IsUse = useSchedule; schedule.WorkDueDate = confirmDate.Value; _context.FmsWorkSchedule.Update(schedule); _context.SaveChanges(); // 실행계획(Request) 생성 if (!_workRequestRepository.IsCreatedRequest(schedule)) { _workRequestRepository.CreateFromWorkSchedule(schedule); } } else { schedule.IsUse = useSchedule; _context.FmsWorkSchedule.Update(schedule); _context.SaveChanges(); } } trans.Complete(); } } // 작업대기로 넘김 public void Order(FmsWorkOrder data) { _workRequestRepository.WorkToOrder(data.SiteId, data.WorkRequestId, data.OrderUserId, data.Content, true); } public IQueryable GetAll() { var query = _context.FmsWorkRequest; return query; } } }