Exemplo n.º 1
0
        /// <summary>
        /// 파일 소스를 삭제한다.
        /// </summary>
        public bool DeleteDataFileSource(Guid formId, Guid formSectionId, Guid fileSourceId)
        {
            using (var repo = new DashboardRepository())
            {
                var dataFileSource = repo.SelectDataFileSource(formId, formSectionId, fileSourceId);
                if (dataFileSource == null)
                {
                    throw new ObjectNotFoundException($"삭제 할 대상 데이터 파일을 찾을 수 없습니다."
                                                      + $"\r\n"
                                                      + $"대시보드 ID: \"{formId}\", 업무 영역 ID: \"{formSectionId}\", 파일 ID: \"{fileSourceId}\"");
                }

                if (repo.DeleteDataFileSource(formId, formSectionId, fileSourceId, CurrentUser.UserId, DateTimeOffset.Now))
                {
                    logger.Info($"데이터 파일을 삭제하였습니다. 파일: \"{dataFileSource.FileName}\""
                                + $"\r\n\r\n"
                                + $"{dataFileSource}");

                    return(true);
                }

                return(false);
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// 파일 소스를 등록한다. 같은 기간에 등록된 파일 소스가 있다면 삭제 처리 된다.
        /// </summary>
        public bool AddDataFileSource(DataFileSource fileSource)
        {
            fileSource.ThrowIfNull(nameof(fileSource));
            fileSource.Validate();

            using (var service = new FormTableService(CurrentUser))
            {
                // 1. FormTable, FormTableSection 체크

                var formTable = service.GetFormTable(fileSource.FormId);
                if (formTable == null)
                {
                    throw new ObjectNotFoundException($"업로드 대상이 되는 대시보드 테이블을 찾을 수 없습니다.\r\n대시보드 ID: \"{fileSource.FormId}\"");
                }
                else if (!formTable.IsEnabled || formTable.IsDeleted)
                {
                    string state = formTable.IsDeleted ? "삭제" : "비활성화";
                    throw new InvalidOperationException($"대상 대시보드 테이블이 {state} 된 상태이므로 파일 데이터를 업로드 할 수 없습니다.\r\n대시보드 ID: \"{fileSource.FormId}\"");
                }

                var formSection = service.GetFormTableSection(fileSource.FormId, fileSource.FormSectionId);
                if (formSection == null)
                {
                    throw new ObjectNotFoundException($"업로드 대상이 되는 업무 영역을 찾을 수 없습니다.\r\n업무영역 ID: \"{fileSource.FormSectionId}\"");
                }
                else if (!formSection.IsEnabled || formSection.IsDeleted)
                {
                    string state = formTable.IsDeleted ? "삭제" : "비활성화";
                    throw new InvalidOperationException($"대상 업무 영역이 {state} 된 상태이므로 파일 데이터를 업로드 할 수 없습니다.\r\n업무영역 ID: \"{fileSource.FormSectionId}\"");
                }

                fileSource.FileTemplateId = formSection.FileTemplate.FileTemplateId;
                fileSource.HtmlTemplateId = formTable.HtmlTemplateId;

                using (var repo = new DashboardRepository())
                {
                    // 3. 실제 파일 경로 체크
                    string filePath = fileSource.GetFileAbsolutePath(DiskPathForDataFileSource);
                    if (!File.Exists(filePath))
                    {
                        logger.Error($"업로드 된 데이터 파일 소스를 찾을 수 없습니다. 파일 경로: \"{filePath}\"");

                        throw new FileNotFoundException($"파일을 찾을 수 없습니다. 파일: \"{fileSource.FileName}\"");
                    }

                    var           allValues = new List <DataFileCellValue>();
                    ExcelFileType fileType;

                    // 4. 파일 타입 체크
                    if (!Enum.TryParse <ExcelFileType>(fileSource.Extension, true, out fileType))
                    {
                        throw new FileLoadException($"지원하지 않는 엑셀 파일 타입입니다. 파일: \"{fileSource.FileName}\"");
                    }

                    // 5. 엑셀로부터 값을 읽음
                    using (var parser = new ExcelParser(filePath, fileType))
                    {
                        var parseOption = formSection.FileTemplate.ParseOption;

                        foreach (var kv in parseOption.Sheets)
                        {
                            foreach (var sheetOption in kv.Value)
                            {
                                string sheetName = kv.Key;

                                var values = parser.GetValuesFromSheet(kv.Key, sheetOption, () =>
                                {
                                    return(new DataFileCellValue(fileSource.FileSourceId, sheetName)
                                    {
                                        CreatedDate = fileSource.CreatedDate
                                    });
                                }).Cast <DataFileCellValue>()
                                             .ToList();

                                allValues.AddRange(values);
                            }
                        }

                        if (!allValues.Any())
                        {
                            logger.Warn($"업로드 된 데이터 파일로부터 읽어들인 엑셀 값이 없습니다. 파일: \"{fileSource.FileName}\""
                                        + $"\r\n\r\n"
                                        + $"{fileSource}");
                        }
                    }

                    // 6. DB에 추가
                    repo.BeginTransaction();

                    try
                    {
                        // 6. 이미 동일한 기간에 해당되는 파일이 있는지 체크
                        // => 있다면 삭제
                        var dateRange         = formTable.GetDateRangeByUploadInterval(fileSource.SourceDate);
                        var oldFileSourceList = repo.SelectDataFileSourceListBySourceDateRange(fileSource.FormId, fileSource.FormSectionId, dateRange.BeginDate, dateRange.EndDate);
                        if (oldFileSourceList != null)
                        {
                            var duplicated = oldFileSourceList
                                             .Where(o => o.FileSourceId != fileSource.FileSourceId)
                                             .ToArray();

                            if (duplicated.Any())
                            {
                                logger.Warn($"해당 기간에 파일 소스가 2개 이상 존재합니다. 파일: {duplicated.Select(o => o.FileName).ToString()}"
                                            + $"\r\n\r\n"
                                            + $"업무 영역 ID: \"{fileSource.FormSectionId}\""
                                            + $"\r\n"
                                            + $"기간: \"{dateRange.BeginDate.ToString("yyyy-MM-dd")}\" ~ \"{dateRange.EndDate.ToString("yyyy-MM-dd")}\"");

                                if (duplicated.Any(o => o.IsConfirmed))
                                {
                                    // 관리자급 권한이 없다면 오류 처리 (관리자는 컨펌된 데이터가 있더라도 업로드 가능하도록 요청)
                                    if (CurrentUser.GroupType < UserPermissionGroupType.Administrator)
                                    {
                                        if (dateRange.BeginDate.ToString("yyyy-MM-dd").Equals(dateRange.EndDate.ToString("yyyy-MM-dd")))
                                        {
                                            throw new InvalidOperationException($"대상 기간에 이미 최종 컨펌된 데이터가 있습니다."
                                                                                + $"\r\n"
                                                                                + $"기간: \"{dateRange.BeginDate.ToString("yyyy-MM-dd")}\"");
                                        }
                                        else
                                        {
                                            throw new InvalidOperationException($"대상 기간에 이미 최종 컨펌된 데이터가 있습니다."
                                                                                + $"\r\n"
                                                                                + $"기간: \"{dateRange.BeginDate.ToString("yyyy-MM-dd")}\" ~ \"{dateRange.EndDate.ToString("yyyy-MM-dd")}\"");
                                        }
                                    }
                                }

                                foreach (var o in duplicated)
                                {
                                    if (repo.DeleteDataFileSource(
                                            formId: o.FormId,
                                            formSectionId: o.FormSectionId,
                                            fileSourceId: o.FileSourceId,
                                            deleterId: CurrentUser.UserId,
                                            deletedDate: DateTimeOffset.Now))
                                    {
                                        logger.Warn($"새로운 데이터를 업로드 하기 위해 대상 기간에 해당되는 데이터 파일이 삭제되었습니다. 파일: \"{o.FileName}\""
                                                    + $"\r\n\r\n"
                                                    + $"기간: \"{dateRange.BeginDate}\" ~ \"{dateRange.EndDate}\""
                                                    + $"\r\n\r\n"
                                                    + $"{o}");
                                    }
                                }
                            }
                        }

                        // 7 파일 데이터 추가
                        if (repo.InsertDataFileSource(fileSource))
                        {
                            if (allValues.Any())
                            {
                                repo.InsertDataFileCellValueList(formTable.FormId, formSection.FormSectionId, fileSource.FileSourceId, allValues, allValues.First().CreatedDate);
                            }

                            repo.CommitTransaction();

                            logger.Info($"새 데이터 파일을 추가하였습니다. 파일: \"{fileSource.FileName}\""
                                        + $"\r\n\r\n"
                                        + $"{fileSource}");

                            return(true);
                        }
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex, $"데이터 파일 추가 중 알 수 없는 오류가 발생하였습니다. 대시보드: \"{formSection.FormName}\", 업무영역: \"{formSection.FormSectionName}\""
                                     + $"\r\n\r\n"
                                     + $"{formSection}");

                        try
                        {
                            repo.RollBackTransaction();
                        }
                        catch (Exception rex)
                        {
                            logger.Fatal(ex, $"데이터 파일 추가 중 치명적인 오류가 발생하였습니다. 대시보드: \"{formSection.FormName}\", 업무영역: \"{formSection.FormSectionName}\""
                                         + $"\r\n\r\n"
                                         + $"{formSection}");

                            ExceptionDispatchInfo.Capture(rex).Throw();
                            // not reached
                        }

                        ExceptionDispatchInfo.Capture(ex).Throw();
                    }

                    return(false); // not reached
                }
            }
        }