فهرست منبع

1차 개발 완료 (날씨API 변경 포함)

ubitems_source 4 سال پیش
والد
کامیت
dc52ee76a2
40فایلهای تغییر یافته به همراه605 افزوده شده و 133 حذف شده
  1. 5 3
      Controllers/AccidentController.cs
  2. 2 1
      Controllers/App/DailyReportController.cs
  3. 4 0
      Controllers/App/ReportHistoryController.cs
  4. 2 3
      Controllers/App/UserController.cs
  5. 1 0
      Controllers/App/WorkHistoryController.cs
  6. 30 3
      Controllers/DailyReportController.cs
  7. 1 1
      Controllers/EnergyUsageController.cs
  8. 2 1
      Controllers/EquipmentController.cs
  9. 19 14
      Controllers/FacilityController.cs
  10. 28 0
      Controllers/HomeController.cs
  11. 60 10
      Controllers/MaterialController.cs
  12. 1 1
      Controllers/MaterialStockController.cs
  13. 15 4
      Controllers/ReportHistoryController.cs
  14. 3 2
      Controllers/UserController.cs
  15. 175 0
      Controllers/WorkBaseController.cs
  16. 2 2
      Controllers/WorkRequestController.cs
  17. 2 1
      Controllers/WorkResultController.cs
  18. 14 0
      Entities/BemsReportHistory.cs
  19. 7 2
      Entities/CmUser.cs
  20. 2 1
      Entities/FmsMaterial.cs
  21. 4 3
      QuartzSchedule/Schedulers/WorkScheduler.cs
  22. 59 59
      Repositories/App/WorkRequestRepository.cs
  23. 4 0
      Services/AnnouncementService.cs
  24. 20 1
      Services/App/MaterialService.cs
  25. 2 0
      Services/App/UserService.cs
  26. 4 0
      Services/CertificateStatusService.cs
  27. 4 1
      Services/ContractManagementService.cs
  28. 6 0
      Services/EnergyDayAnalysisService.cs
  29. 4 0
      Services/GuidelineService.cs
  30. 4 1
      Services/LayoutService.cs
  31. 8 5
      Services/MaterialService.cs
  32. 2 4
      Services/MaterialStockService.cs
  33. 4 1
      Services/OrganizationChartStatusService.cs
  34. 4 1
      Services/RentalStatusService.cs
  35. 3 2
      Services/SiteWeatherInfoService.cs
  36. 4 0
      Services/SurveyService.cs
  37. 3 2
      Services/UserService.cs
  38. 87 0
      Services/WorkBaseService.cs
  39. 2 2
      appsettings.Development.json.example
  40. 2 2
      appsettings.json.example

+ 5 - 3
Controllers/AccidentController.cs

@@ -234,7 +234,7 @@ namespace FMSAdmin.Controllers {
                 AccidentCodeTypeName = x.FmsAccidentCodeType.Name,
                 x.StartDate,
                 x.EndDate,
-                ClosingDate = x.ClosingDate.Value.ToString("yyyy/MM/dd"),
+                ClosingDate = x.ClosingDate != null ? x.ClosingDate.Value.ToString("yyyy/MM/dd") : "",
                 CompanyName = x.CmCompany.Name,
                 DepartmentName = x.CmDepartment.Name,
                 x.CompanyId,
@@ -244,8 +244,10 @@ namespace FMSAdmin.Controllers {
                 x.Action2,
                 x.Damage,
                 x.Measurement,
-                CmFileUrl1 = _storage.ParseFileUrl(x.CmFile1),
-                CmFileUrl2 = _storage.ParseFileUrl(x.CmFile2),
+                CmFileUrl1 = x.CmFile1 != null && x.CmFile1.ContentType.IndexOf("image/") != -1 ? _storage.ParseFileUrl(x.CmFile1) : "",
+                CmFileUrl2 = x.CmFile2 != null && x.CmFile2.ContentType.IndexOf("image/") != -1 ? _storage.ParseFileUrl(x.CmFile2) : "",
+                CmFileUrl3 = x.CmFile3 != null && x.CmFile3.ContentType.IndexOf("image/") != -1 ? _storage.ParseFileUrl(x.CmFile3) : "",
+                CmFileUrl4 = x.CmFile4 != null && x.CmFile4.ContentType.IndexOf("image/") != -1 ? _storage.ParseFileUrl(x.CmFile4) : "",
                 x.Firstwitness,
                 x.VictimAge,
                 x.VictimName,

+ 2 - 1
Controllers/App/DailyReportController.cs

@@ -136,7 +136,8 @@ namespace FMSApp.Controllers {
             var yesterday = addDate.Date.AddDays(-1);
             var tomorrow = addDate.Date.AddDays(1);
             var currentMonthFirstDay = new DateTime(addDate.Year, addDate.Month, 1);
-            var prevMonthFirstDay = new DateTime(addDate.Year, addDate.Month - 1, 1);
+            // var prevMonthFirstDay = new DateTime(addDate.Year, addDate.Month - 1, 1);
+            var prevMonthFirstDay = addDate.Date.AddMonths(-1).AddDays(1 - addDate.Day);
 
             var site = _context.CmSite.FirstOrDefault(x => x.SiteId == Util.ToInt(siteId));
             var sido = _siteWeatherInfoService.ReplaceSido(site.ApiSido ?? "");

+ 4 - 0
Controllers/App/ReportHistoryController.cs

@@ -92,8 +92,12 @@ namespace FMSApp.Controllers {
                 history.ReportFormatId,
                 history.FormatName,
                 history.Writer,
+                ApproverUserStamp1 = history.ApproverUser1 != null ? _storage.ParseFile(history.ApproverUser1.CmFile1) : null,
+                ApproverUserStamp2 = history.ApproverUser2 != null ? _storage.ParseFile(history.ApproverUser2.CmFile1) : null,
                 history.Confirm1,
                 history.Confirm2,
+                ApproveDate1 = history.ApproveDate1 != null ? history.ApproveDate1.Value.ToString("yyyy-MM-dd") : "",
+                ApproveDate2 = history.ApproveDate2 != null ? history.ApproveDate2.Value.ToString("yyyy-MM-dd") : "",
                 history.FileName,
                 BusinessFieldName = Util.V(history, x => x.BemsReportFormat.CmBusinessField.Name),
                 Content = builder.ToString(),

+ 2 - 3
Controllers/App/UserController.cs

@@ -50,7 +50,8 @@ namespace FMSApp.Controllers {
 
             if (user == null)
                 return BadRequest("아이디나 비밀번호가 잘못되었습니다.");
-
+            if (user.EmploymentStatus == EmploymentStatus.퇴직)
+                return BadRequest("로그인 할 수 없습니다.");
             return Ok(new {
                 user.SiteId,
                 SiteName = user.CmSite.Name,
@@ -244,10 +245,8 @@ namespace FMSApp.Controllers {
 
             // 기본 Entity 검색
             query = query.Filter(req.conditions);
-
             // 기본 Entity 정렬
             query = query.Sort(req.sort);
-
             return query;
         }
 

+ 1 - 0
Controllers/App/WorkHistoryController.cs

@@ -159,6 +159,7 @@ namespace FMSApp.Controllers {
                 x.WorkPrice,
                 x.WorkItem,
                 x.WorkEndDate,
+                x.WorkUsers,
                 CmFile = _storage.ParseFile(x.CmFile),
                 FmsWorkOrder = new {
                     x.FmsWorkOrder.OrderDate,

+ 30 - 3
Controllers/DailyReportController.cs

@@ -156,7 +156,8 @@ namespace FMSAdmin.Controllers {
             var yesterday = addDate.Date.AddDays(-1);
             var tomorrow = addDate.Date.AddDays(1);
             var currentMonthFirstDay = new DateTime(addDate.Year, addDate.Month, 1);
-            var prevMonthFirstDay = new DateTime(addDate.Year, addDate.Month - 1, 1);
+            // var prevMonthFirstDay = new DateTime(addDate.Year, addDate.Month - 1, 1);
+            var prevMonthFirstDay = addDate.Date.AddMonths(-1).AddDays(1 - addDate.Day);
 
             var site = _context.CmSite.FirstOrDefault(x => x.SiteId == Util.ToInt(siteId));
             var sido = _siteWeatherInfoService.ReplaceSido(site.ApiSido);
@@ -503,12 +504,38 @@ namespace FMSAdmin.Controllers {
                         }
                     }
                 }
+
+                var materialList = new JArray();
+                if (jsonObject.Materials != null)
+                    foreach (dynamic material in jsonObject.Materials) {
+                        if (material != null) {
+                            if (material.List == null) {
+                                material.List = new JArray();
+                            }
+                            foreach (dynamic i in material.List) {
+                                materialList.Add(JToken.FromObject(new {
+                                    BusinessFieldName = material.BusinessFieldName,
+                                    ReleaseType = i.ReleaseTypeName,
+                                    FirstClass = i.FirstClassName,
+                                    SecondClass = i.SecondClassName,
+                                    ThirdClass = i.ThirdClassName,
+                                    MaterialName = i.MaterialName,
+                                    Standard = i.Standard,
+                                    Unit = i.Unit,
+                                    MaterialCount = i.MaterialCount,
+                                    WorkName = i.WorkName,
+                                    WorkerName = i.WorkerName
+                                }));
+                            }
+                        }
+                    }
+
+
                 jsonObject.EnergiesTotal = energiesTotal;
                 jsonObject.WorkList = workList;
-
+                jsonObject.MaterialList = materialList;
                 datas = JsonConvert.SerializeObject(jsonObject);
             }
-
             string json = "";
             if (item != null)
                 json = $@"

+ 1 - 1
Controllers/EnergyUsageController.cs

@@ -343,7 +343,7 @@ namespace FMSAdmin.Controllers {
 
         public IDictionary<string, EnergyDaily> convertTOE(IDictionary<string, EnergyDaily> list, DateTime start, DateTime end, EnergyInterval interval) {
             var date = start;
-            var days = interval == EnergyInterval.월 ? (end.Month - start.Month) + 12 * (end.Year - start.Year) + 1 : end.Subtract(start).Days;
+            var days = interval == EnergyInterval.월 ? (end.Month - start.Month) + 12 * (end.Year - start.Year) + 1 : end.Subtract(start).Days + 1;
 
             for (var i = 0; i < days; i++) {
                 var dateStr = date.ToString("yyyy-MM-dd");

+ 2 - 1
Controllers/EquipmentController.cs

@@ -122,7 +122,8 @@ namespace FMSAdmin.Controllers {
                 x.Unit,
                 x.SupplierName,
                 x.SupplierPhoneNo,
-                TotalStockCount = x.FmsEquipmentHistory.Where(x => x.EquipmentHistoryId == historyId).Select(x => x.TotalStockCount).FirstOrDefault(),
+                TotalStockCount = _context.SiteConfig.Single().UseEquipmentRent ? x.FmsEquipmentHistory.Where(x => x.EquipmentHistoryId == historyId).Select(x => x.TotalStockCount).FirstOrDefault()
+                                                                                : x.FmsEquipmentHistory.Where(x => x.EquipmentId == id).OrderByDescending(x => x.EquipmentHistoryId).Select(x => x.TotalStockCount).FirstOrDefault(),
                 CurrentStockCount = x.FmsEquipmentHistory.Where(x => x.EquipmentHistoryId == historyId).Select(x => x.CurrentStockCount).FirstOrDefault(),
             });
             return Ok(item.First());

+ 19 - 14
Controllers/FacilityController.cs

@@ -109,6 +109,7 @@ namespace FMSAdmin.Controllers {
                 x.Note,
                 x.Sort1,
                 x.Sort2,
+                FacilityLoc = x.CmBuilding.Name + "-"  + x.CmFloor.Name + "-" + x.CmZone.Name
             }).AsEnumerable().OrderBy(x => x.SiteSort).ThenBy(x => x.FacilityTypeId).ThenBy(x => x.Sort1).ThenBy(x => x.Sort2).AsQueryable();
             //설비명 Sort 때문에 임시. 후에 수정해야 함.
             return list;
@@ -134,30 +135,28 @@ namespace FMSAdmin.Controllers {
                 // x.ManufactureModel,
                 // x.FacilityCapacity,
                 // FacilityLoc = x.CmFloor.Name,
-
                 x.SiteId,
                 SiteName = x.CmSite.Name,
                 x.FacilityCode,
-                FirstClassId = x.FmsFacilityCodeClass.FacilityClassId,
-                FirstClassName = x.FmsFacilityCodeClass.Name,
-                SecondClassId = x.FmsFacilityCodeClass1.FacilityClassId,
-                SecondClassName = x.FmsFacilityCodeClass1.Name,
                 FmsFacilityCodeType = x.BemsFacilityType.Name,
-                ThirdClassId = x.FmsFacilityCodeClass2.FacilityClassId,
-                ThirdClassName = x.FmsFacilityCodeClass2.Name,
-                IsUse = Util.ToBool(x.IsUse) ? "활성화" : "취소",
-                FacilityName = x.Name,
-                x.ManufactureModel,
-                x.FacilityCapacity,
-                x.Rfid,
                 x.DeviceType,
+                FacilityName = x.Name,
                 x.Nickname,
                 x.FacilityUsage,
                 x.Manufacturer,
                 ManufactureDate = x.ManufactureDate != null ? Convert.ToDateTime(x.ManufactureDate).ToString("yyyyMMdd") : "",
+                //FirstClassId = x.FmsFacilityCodeClass.FacilityClassId,
+                FirstClassName = x.FmsFacilityCodeClass.Name,
+                //SecondClassId = x.FmsFacilityCodeClass1.FacilityClassId,
+                SecondClassName = x.FmsFacilityCodeClass1.Name,
+                //ThirdClassId = x.FmsFacilityCodeClass2.FacilityClassId,
+                ThirdClassName = x.FmsFacilityCodeClass2.Name,
+                x.FacilityCapacity,
+                x.Rfid,
                 x.RatedPowerConsumption,
                 x.RatedCop,
                 x.ManufactureSerial,
+                x.ManufactureModel,
                 x.Supplier,
                 x.SupplierPhoneNo,
                 FirstdFacilityLoc = x.CmBuilding.Name,
@@ -171,8 +170,14 @@ namespace FMSAdmin.Controllers {
                 x.FacilityCount,
                 FuelType = x.BemsFuelType.Name,
                 ContractType = x.BemsNoticePriceContractType.Name,
-                x.Note
-            });
+                x.Note,
+                IsUse = Util.ToBool(x.IsUse) ? "활성화" : "취소",
+                x.FacilityTypeId,
+                SiteSort = x.CmSite.SortOrderNo,
+                x.Sort1,
+                x.Sort2,
+            }).AsEnumerable().OrderBy(x => x.SiteSort).ThenBy(x => x.FacilityTypeId).ThenBy(x => x.Sort1).ThenBy(x => x.Sort2).AsQueryable();
+            //설비명 Sort 때문에 임시. 후에 수정해야 함.
 
             var stream = new MemoryStream();
             using (var package = new ExcelPackage(stream)) {

+ 28 - 0
Controllers/HomeController.cs

@@ -40,5 +40,33 @@ namespace FMSAdmin.Controllers {
             return Content("api server");
         }
 
+
+        [HttpGet("[action]")]
+        public IActionResult EmailTest() {
+            // 이메일 테스트
+            using (var message = new MailMessage()) {
+                // 받는사람
+                message.To.Add(new MailAddress("테스트@gmail.com", "테스트"));
+
+                // 보내는사람
+                message.From = new MailAddress("hdc.icontrols.rnd1@gmail.com", "FMS");
+                //message.CC.Add(new MailAddress("cc@email.com", "CC Name"));
+                //message.Bcc.Add(new MailAddress("bcc@email.com", "BCC Name"));
+                message.Subject = "이메일 인증 테스트";
+                message.Body = "코드는 2390423 입니다.";
+                message.IsBodyHtml = true;
+                var smtp = new SmtpClient {
+                    Host = "smtp.gmail.com",
+                    Port = 587,
+                    EnableSsl = true,
+                    DeliveryMethod = SmtpDeliveryMethod.Network,
+                    Credentials = new NetworkCredential("hdc.icontrols.rnd1@gmail.com", "pwrd12#$"),
+                    Timeout = 20000
+                };
+                smtp.Send(message);
+            }
+            return Content(":)");
+        }
+
     }
 }

+ 60 - 10
Controllers/MaterialController.cs

@@ -21,6 +21,7 @@ using System.Collections.Generic;
 using System.Collections;
 using OfficeOpenXml.Style;
 using System.Drawing;
+using System.IO.Compression;
 
 namespace FMSAdmin.Controllers {
     [Authorize]
@@ -119,7 +120,7 @@ namespace FMSAdmin.Controllers {
             var useMaterialReasonableStockCount = _context.SiteConfig.Single().UseMaterialReasonableStockCount;
             using (ExcelPackage excelPackage = new ExcelPackage(excelFile.OpenReadStream())) {
                 var worksheet = excelPackage.Workbook.Worksheets[0];
-                int colCnt = isAdmin ? 15 : 14;
+                int colCnt = isAdmin ? 14 : 13;
                 if (!useMaterialType) colCnt -= 1;
 
                 //헤더세팅
@@ -134,7 +135,8 @@ namespace FMSAdmin.Controllers {
                         var class2 = excelUploadHelper.GetValue(worksheet, "자재 중분류", i);
                         var class3 = excelUploadHelper.GetValue(worksheet, "자재 소분류", i);
                         var type = useMaterialType ? excelUploadHelper.GetValue(worksheet, "자재구분(*)", i, true) : "";
-                        var qrCode = excelUploadHelper.GetValue(worksheet, "QR코드", i);
+                        //현대해상 자재qr코드 숨김처리 
+                        //var qrCode = excelUploadHelper.GetValue(worksheet, "QR코드", i);
                         var unit = excelUploadHelper.GetValue(worksheet, "단위", i);
                         var durableYears = excelUploadHelper.GetValue(worksheet, "내용연수", i);
                         var reasonableStockCount = useMaterialReasonableStockCount ? excelUploadHelper.GetValue(worksheet, "적정재고량", i) : null;
@@ -191,7 +193,7 @@ namespace FMSAdmin.Controllers {
                             Name = name,
                             FirstClassId = classId1,
                             MaterialTypeId = typeId,
-                            Rfid = qrCode,
+                            Rfid = "", //qrCode,
                             Unit = unit,
                             Manufacturer = manufacturer,
                             Standard = standard,
@@ -224,19 +226,19 @@ namespace FMSAdmin.Controllers {
                                                 && x.Standard == material.Standard).Select(x => x.ExcelRowNum).SingleOrDefault();
                         if (overlapRowNum != 0)
                             throw new ServiceException("파일 내 동일 정보가 존재합니다.[업무분야-자재명-규격]" + "(" + (overlapRowNum) + "번 행 - " + (i) + "번 행)");
+                        //현대해상 자재qr코드 숨김처리 
+                        //overlapRowNum = list.Where(x => x.Rfid == material.Rfid && Util.IsNullOrEmpty(material.Rfid) == false).Select(x => x.ExcelRowNum).SingleOrDefault();
 
-                        overlapRowNum = list.Where(x => x.Rfid == material.Rfid && Util.IsNullOrEmpty(material.Rfid) == false).Select(x => x.ExcelRowNum).SingleOrDefault();
-
-                        if (overlapRowNum != 0)
-                            throw new ServiceException("파일 내 동일 정보가 존재합니다.[QR코드]" + "(" + (overlapRowNum) + "번 행 - " + (i) + "번 행)");
+                        // if (overlapRowNum != 0)
+                        //     throw new ServiceException("파일 내 동일 정보가 존재합니다.[QR코드]" + "(" + (overlapRowNum) + "번 행 - " + (i) + "번 행)");
 
 
                         if (_service.checkName(material, true) > 0) {
                             throw new ServiceException("기존 자재 정보와 동일 정보가 존재합니다.[업무분야-자재명-규격]" + rowName);
                         }
-
-                        if (!Util.IsNullOrEmpty(material.Rfid) && _service.checkRfid(material, true) > 0)
-                            throw new ServiceException("기존 자재 정보와 동일 정보가 존재합니다.[QR코드]" + rowName);
+                        //현대해상 자재qr코드 숨김처리 
+                        // if (!Util.IsNullOrEmpty(material.Rfid) && _service.checkRfid(material, true) > 0)
+                        //     throw new ServiceException("기존 자재 정보와 동일 정보가 존재합니다.[QR코드]" + rowName);
 
                         list.Add(material);
 
@@ -440,5 +442,53 @@ namespace FMSAdmin.Controllers {
 
             return sortQuery;
         }
+
+        [HttpGet("qr")]
+        public IActionResult QRDown([FromQuery] PagingRequest req) {
+
+            req.page = 1;
+            req.limit = 0;
+            var query = _FilterAndSort(req);
+
+
+            var Folder = DateTime.Now.ToString("yyyyMMddhhmmsss");
+            var FileName = "자재 QR코드_" + Folder;
+            var downFile = "/files/temp/qr/" + FileName + ".zip";
+
+            var list = query.Where(x => x.Material.Rfid != null && x.Material.Rfid != "" && x.Material.IsUse == true).Select(x => new {
+                x.Material.SiteId,
+                x.Material.MaterialId,
+                x.Material.Rfid
+            });
+
+            if (list.Count() == 0) throw new ServiceException("다운로드 가능한 QR코드가 없습니다.");
+
+            using (MemoryStream newZip = new MemoryStream()) {
+                //using (FileStream newZip = new FileStream(@"c:\users\exampleuser\release.zip", FileMode.CreateNew)) {
+                using (ZipArchive archive = new ZipArchive(newZip, ZipArchiveMode.Create)) {
+                    foreach (var item in list) {
+                        archive.CreateEntryFromFile(_storage.GetLocalPath($"/qr/material/{item.SiteId}_{item.MaterialId}.jpg"), $"{item.SiteId}_{item.MaterialId}.jpg");
+                    }
+                }
+                return File(newZip.ToArray(), "application/zip", FileName);
+            }
+        }
+
+        [HttpGet("QrCodeRegen")]
+        [AllowAnonymous]
+        public IActionResult QrCodeRegen() {
+            var query = _service.GetAll();
+            var list = query.Where(x => x.Rfid != null && x.Rfid != "").Select(x => new {
+                x.SiteId,
+                x.MaterialId,
+                x.Rfid,
+            });
+
+            foreach (var item in list) {
+                _QrCode.Save(item.Rfid, $"{item.SiteId}_{item.MaterialId}", "Material");
+            }
+
+            return Content(":)");
+        }
     }
 }

+ 1 - 1
Controllers/MaterialStockController.cs

@@ -268,7 +268,7 @@ namespace FMSAdmin.Controllers {
                 x.Material.ReasonableStockCount,
                 x.StockCount,
                 x.StockAmount,
-                InsufficientStock = Util.ToLong(x.Material.ReasonableStockCount) - x.StockCount,
+                InsufficientStock = (Util.ToLong(x.Material.ReasonableStockCount) - x.StockCount > 0) ? Util.ToLong(x.Material.ReasonableStockCount) - x.StockCount : 0,
                 x.Warehouse.WarehouseId,
                 WareHouseName = x.Warehouse.Name,
                 x.Material.FinalPrice,

+ 15 - 4
Controllers/ReportHistoryController.cs

@@ -128,8 +128,12 @@ namespace FMSAdmin.Controllers {
                 x.FormatName,
                 x.Writer,
                 CmFile = _storage.ParseFile(x.CmFile),
+                ApproverUser1 = x.ApproverUser1 != null ? _storage.ParseFile(x.ApproverUser1.CmFile1) : null,
+                ApproverUser2 = x.ApproverUser2 != null ? _storage.ParseFile(x.ApproverUser2.CmFile1) : null,
                 x.Confirm1,
                 x.Confirm2,
+                ApproveDate1 = x.ApproveDate1 != null ? x.ApproveDate1.Value.ToString("yyyy-MM-dd") : "",
+                ApproveDate2 = x.ApproveDate2 != null ? x.ApproveDate2.Value.ToString("yyyy-MM-dd") : "",
                 BemsReportHistoryContent = x.BemsReportHistoryContent.Select(f => new {
                     f.ContentId,
                     f.Content
@@ -214,11 +218,18 @@ namespace FMSAdmin.Controllers {
 
 
         [HttpGet("[action]")]
-        public IActionResult Confirm([FromQuery] int siteId, [FromQuery] int seq, [FromQuery] int type, [FromQuery] string name) {
+        public IActionResult Confirm([FromQuery] int siteId, [FromQuery] int seq, [FromQuery] int type, [FromQuery] string approverUserId, [FromQuery] string approverUserName) {
             var persist = _context.BemsReportHistory.Where(x => x.SiteId == siteId && x.Seq == seq).FirstOrDefault();
-
-            if (type == 1) persist.Confirm1 = name;
-            if (type == 2) persist.Confirm2 = name;
+            if (type == 1) {
+                persist.ApproverUserId1 = approverUserId;
+                persist.Confirm1 = approverUserName;
+                persist.ApproveDate1 = DateTime.Now;
+            }
+            if (type == 2) {
+                persist.ApproverUserId2 = approverUserId;
+                persist.Confirm2 = approverUserName;
+                persist.ApproveDate2 = DateTime.Now;
+            }
             _context.BemsReportHistory.Update(persist);
             _context.SaveChanges();
 

+ 3 - 2
Controllers/UserController.cs

@@ -54,7 +54,8 @@ namespace FMSAdmin.Controllers {
             var user = _service.Login(model);
             if (user == null)
                 return BadRequest("아이디나 비밀번호가 잘못되었습니다.");
-
+            if (user.EmploymentStatus == EmploymentStatus.퇴직)
+                return BadRequest("로그인 할 수 없습니다.");
             return Ok(new {
                 user.SiteId,
                 user.UserId,
@@ -492,7 +493,7 @@ namespace FMSAdmin.Controllers {
             }
 
             // 검증완료 비밀번호 초기화
-            _service.ChangePassword(member.SiteId, member.UserId, member.UserId);
+            _service.ChangePassword(member.SiteId, member.UserId, member.UserId, true);
             return Ok(new {
                 SiteId = member.SiteId,
                 UserId = member.UserId,

+ 175 - 0
Controllers/WorkBaseController.cs

@@ -0,0 +1,175 @@
+using System;
+using System.IO;
+using System.Linq;
+using FMSAdmin.Data;
+using FMSAdmin.Entities;
+using FMSAdmin.Helpers;
+using FMSAdmin.Models;
+using FMSAdmin.Services;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using OfficeOpenXml;
+using Microsoft.AspNetCore.Http;
+using System.Collections.Generic;
+using System.Drawing;
+using OfficeOpenXml.Style;
+
+namespace FMSAdmin.Controllers {
+    [Authorize]
+    [ApiController]
+    [ApiVersion("1")]
+    [Route("api/[controller]")]
+    public class WorkBaseController : Controller {
+        private readonly ILogger<WorkBaseController> _logger;
+        private readonly FMSContext _context;
+        private readonly WorkBaseService _service;
+
+        public WorkBaseController(
+            ILogger<WorkBaseController> logger,
+            FMSContext context,
+            WorkBaseService service
+            ) {
+            _logger = logger;
+            _context = context;
+            _service = service;
+        }
+
+        [HttpPost]
+        [Route("[action]")]
+        public IActionResult ImportExcelAdmin(IFormFile excelFile) {
+            return (ImportExcel(excelFile, true));
+        }
+
+        [HttpPost]
+        [Route("[action]")]
+        public IActionResult ImportExcelAuthBusiness(IFormFile excelFile) {
+            return (ImportExcel(excelFile, false, true));
+        }
+
+        /// <summary>
+        /// 엑셀파일 임포트
+        /// </summary>
+        /// <param name="file"></param>
+        /// <returns></returns>
+        [HttpPost]
+        [Route("[action]")]
+        public IActionResult ImportExcel(IFormFile excelFile, bool isAdmin = false, bool authBusiness = false) {
+            IList<FmsWorkRequest> list = new List<FmsWorkRequest>();
+            var userInfo = _context.CmUser.Where(x => x.UserId == User.Identity.Name).SingleOrDefault();
+            using (ExcelPackage excelPackage = new ExcelPackage(excelFile.OpenReadStream())) {
+                var worksheet = excelPackage.Workbook.Worksheets[0];
+                int colCnt = isAdmin ? 14 : 13;
+                //헤더세팅
+
+                ExcelUploadHepler excelUploadHelper = new ExcelUploadHepler();
+                excelUploadHelper.GenerateColumns(worksheet, 1, colCnt);
+                for (int i = worksheet.Dimension.Start.Row + 2; i <= worksheet.Dimension.End.Row; i++) {
+                    if (!excelUploadHelper.IsRowEmpty(worksheet, i, colCnt)) {
+                        var site = isAdmin ? excelUploadHelper.GetValue(worksheet, "현장ID *(필수)", i, true) : "";
+                        var reqUserId = excelUploadHelper.GetValue(worksheet, "작업자 ID *(필수)", i, true);
+                        var workTypeId = excelUploadHelper.GetValue(worksheet, "작업구분 *(필수)", i, true);
+                        var workDetailTypeId1 = excelUploadHelper.GetValue(worksheet, "수시계획구분", i);
+                        var workDetailTypeId2 = excelUploadHelper.GetValue(worksheet, "공사계획구분", i);
+                        var business = excelUploadHelper.GetValue(worksheet, "업무분야 *(필수)", i, true);
+                        var title = excelUploadHelper.GetValue(worksheet, "업무명 *(필수)", i, true);
+                        var content = excelUploadHelper.GetValue(worksheet, "업무(신청)내용", i);
+                        var facilityName = excelUploadHelper.GetValue(worksheet, "대상설비", i);
+                        var partnerName = excelUploadHelper.GetValue(worksheet, "업체명", i);
+                        var workPrice = excelUploadHelper.GetValue(worksheet, "금액", i);
+                        var workUser = excelUploadHelper.GetValue(worksheet, "작업자 *(필수)", i, true);
+                        var workStartDate = excelUploadHelper.GetValue(worksheet, "작업일시 시작일 *(필수)", i, true).Replace("-", "");
+                        var workEndDate = excelUploadHelper.GetValue(worksheet, "작업일시 종료일 *(필수)", i, true).Replace("-", "");
+
+                        _logger.LogInformation("site " + site);
+                        _logger.LogInformation("worEndDate : " + workEndDate);
+
+                        var rowName = "(" + (i) + "번 행)";
+
+                        var siteId = isAdmin ? _context.CmSite.Where(x => x.SiteId == Util.ToInt(site) && x.IsUse == true).Select(x => x.SiteId).SingleOrDefault() : userInfo.SiteId;
+                        var businessId = _context.CmBusinessField.Where(x => x.BusinessFieldId == Util.ToInt(business) && x.IsUse == true).Select(x => x.BusinessFieldId).SingleOrDefault();
+                        var reqUser = _context.CmUser.Where(x => x.UserId == reqUserId && x.IsUse == true).Select(x => x.Name).SingleOrDefault();
+                        var workType = _context.FmsWorkCodeType.Where(x => x.WorkTypeId == Util.ToInt(workTypeId)).Select(x => x.Name).SingleOrDefault();
+                        var partner = (partnerName != null) ? _context.CmPartner.Where(x => x.SiteId == siteId && x.Name == partnerName).Select(x => x.PartnerId).ToList() : null;
+                        if (partner != null && partner.Count > 1) {
+                            throw new ServiceException($"등록된 업체명 중 동일한 업체명이 2개 이상 있습니다. {rowName}");
+                        }
+                        var partnerId = (partnerName != null) ? _context.CmPartner.Where(x => x.SiteId == siteId && x.Name == partnerName).Select(x => x.PartnerId).SingleOrDefault() : 0;
+
+                        // 계획구분 (수시(5), 공사(6))
+                        int? workDetailTypeId = null;
+                        if (workTypeId == "5") {
+                            string[] tmpA = { "41", "42" };
+                            workDetailTypeId = (Util.S(workDetailTypeId1) == "" || !tmpA.Contains(workDetailTypeId1)) ? 42 : Util.ToInt(workDetailTypeId1);
+                        } else if (workTypeId == "6") {
+                            string[] tmpA = { "43", "44", "45", "46", "47", "48" };
+                            workDetailTypeId = (Util.S(workDetailTypeId2) == "" || !tmpA.Contains(workDetailTypeId2)) ? 48 : Util.ToInt(workDetailTypeId2);
+                        }
+
+                        if (isAdmin) excelUploadHelper.EntityIdCheck(siteId, "사옥", rowName);
+                        excelUploadHelper.EntityIdCheck(reqUser, "작업자ID", rowName);
+                        excelUploadHelper.EntityIdCheck(workType, "작업구분", rowName);
+                        excelUploadHelper.NumericCheck(workTypeId, "작업구분", rowName);
+                        excelUploadHelper.EntityIdCheck(businessId, "업무분야", rowName);
+                        excelUploadHelper.NumericCheck(business, "업무분야", rowName);
+                        excelUploadHelper.EntityIdCheck(title, "업무명", rowName);
+                        excelUploadHelper.EntityIdCheck(workUser, "작업자", rowName);
+
+                        excelUploadHelper.NumericCheck(workPrice, "금액", rowName);
+
+                        workStartDate = excelUploadHelper.DateTimeCheck(workStartDate, "작업일시 시작일", rowName);
+                        workEndDate = excelUploadHelper.DateTimeCheck(workEndDate, "작업일시 종료일", rowName);
+
+                        if (partnerName != null) {
+                            excelUploadHelper.EntityIdCheck(partnerId, "업체명", rowName);
+                        }
+
+                        var baseRequest = new FmsWorkRequest {
+                            SiteId = siteId,
+                            WorkTypeId = Util.ToInt(workTypeId),
+                            WorkDetailTypeId = workDetailTypeId,
+                            BusinessFieldId = businessId,
+                            WorkProgressId = 1,
+                            Title = title,
+                            Content = content,
+                            RequestUserId = reqUserId,
+                            RequestDate = DateTime.Parse(workStartDate),
+                            StartWorkDate = DateTime.Parse(workStartDate),
+                            WorkUsers = workUser,
+                            WorkPartnerId = partnerId,
+                            WorkEndDate = DateTime.Parse(workEndDate),
+                        };
+                        if (workPrice != null) baseRequest.WorkPrice = Util.ToInt(workPrice);
+
+                        if (facilityName != null) {
+                            var arrFacilityName = facilityName.Split(',');
+                            for (var arrNum = 0; arrNum < arrFacilityName.Length; arrNum++) {
+                                var facilityCode = _context.CmFacility.Where(x => x.SiteId == siteId && x.Name == arrFacilityName[arrNum] && x.IsUse == true).Select(x => x.FacilityCode).SingleOrDefault();
+                                excelUploadHelper.EntityIdCheck(facilityCode, "설비명", rowName);
+
+                                baseRequest.FmsWorkRequestToFacility.Add(new FmsWorkRequestToFacility() {
+                                    SiteId = siteId,
+                                    FacilityCode = facilityCode,
+                                });
+                            }
+                        }
+
+                        if (!ModelState.IsValid) throw new ServiceException(string.Join(" ",
+                                        ModelState.Values
+                                        .SelectMany(x => x.Errors)
+                                        .Select(x => x.ErrorMessage)) + rowName);
+
+                        list.Add(baseRequest);
+                    }
+                }
+            }
+            if (list.Count > 0) {
+                _service.ImportExcel(list, User.Identity.Name);
+
+                return Ok($"엑셀업로드를 성공하였습니다. {list.Count}건의 데이터가 등록되었습니다.");
+            } else {
+                throw new ServiceException("등록할 데이터가 없습니다.");
+            }
+        }
+    }
+}

+ 2 - 2
Controllers/WorkRequestController.cs

@@ -234,8 +234,8 @@ namespace FMSAdmin.Controllers {
                 WorkDetailType = x.WorkDetailType.Name,
                 x.WorkRequestId,
                 x.Title,
-                StartWorkDate = x.StartWorkDate.ToShortDateString(),
-                EndWorkDate = x.WorkEndDate,
+                StartWorkDate = x.StartWorkDate.ToString("yyyy-MM-dd"),
+                EndWorkDate = x.WorkEndDate != null ? x.WorkEndDate.Value.ToString("yyyy-MM-dd") : "",
                 CmUserNavigation = x.CmUserNavigation.Name,
                 x.WorkScheduleId,
                 x.WorkProgressId,

+ 2 - 1
Controllers/WorkResultController.cs

@@ -394,7 +394,8 @@ namespace FMSAdmin.Controllers {
                 },
                 FmsWorkRequest = new {
                     x.FmsWorkRequest.Content,
-                    x.FmsWorkRequest.WorkUsers
+                    x.FmsWorkRequest.WorkUsers,
+                    x.FmsWorkRequest.StartWorkDate,
                 },
                 x.StartDate,
                 x.EndDate,

+ 14 - 0
Entities/BemsReportHistory.cs

@@ -50,6 +50,15 @@ namespace FMSAdmin.Entities {
 
         public int? FileId { get; set; }
 
+        [Display(Name = "팀장확인")]
+        public string ApproverUserId1 { get; set; }
+
+        [Display(Name = "소장확인")]
+        public string ApproverUserId2 { get; set; }
+        [Column(TypeName = "date")]
+        public DateTime? ApproveDate1 { get; set; }
+        [Column(TypeName = "date")]
+        public DateTime? ApproveDate2 { get; set; }
         [ForeignKey("SiteId")]
         public virtual CmSite Site { get; set; }
 
@@ -63,5 +72,10 @@ namespace FMSAdmin.Entities {
 
         [InverseProperty("BemsReportHistory")]
         public virtual ICollection<BemsReportHistoryContent> BemsReportHistoryContent { get; set; }
+
+        [ForeignKey("ApproverUserId1")]
+        public virtual CmUser ApproverUser1 { get; set; }
+        [ForeignKey("ApproverUserId2")]
+        public virtual CmUser ApproverUser2 { get; set; }
     }
 }

+ 7 - 2
Entities/CmUser.cs

@@ -12,7 +12,7 @@ namespace FMSAdmin.Entities {
     public enum EmploymentStatus {
         재직 = 1,
         휴직,
-        퇴직
+        퇴직,
     }
 
     public partial class CmUser {
@@ -52,6 +52,8 @@ namespace FMSAdmin.Entities {
             MobileShortcuts = new List<MobileShortcut>();
             CmRentalStatus = new HashSet<CmRentalStatus>();
             CmSurvey = new HashSet<CmSurvey>();
+            BemsReportFormatCmUser = new HashSet<BemsReportHistory>();
+            BemsReportFormatCmUserNavigation = new HashSet<BemsReportHistory>();
         }
 
         [Display(Name = "현장 고유번호")]
@@ -248,7 +250,10 @@ namespace FMSAdmin.Entities {
         public virtual ICollection<CmRentalStatus> CmRentalStatus { get; set; }
         [InverseProperty("CmUser")]
         public virtual ICollection<CmSurvey> CmSurvey { get; set; }
-
+        [InverseProperty("ApproverUser1")]
+        public virtual ICollection<BemsReportHistory> BemsReportFormatCmUser { get; set; }
+        [InverseProperty("ApproverUser2")]
+        public virtual ICollection<BemsReportHistory> BemsReportFormatCmUserNavigation { get; set; }
         [NotMapped]
         public string AccessToken { get; set; }
         [NotMapped]

+ 2 - 1
Entities/FmsMaterial.cs

@@ -123,7 +123,8 @@ namespace FMSAdmin.Entities {
             throw new NotImplementedException();
         }
         public static Expression<Func<FmsMaterial, long>> GetStockCount =
-            (x) => x.FmsMaterialStored.Where(s => s.IsApproval == true).OrderByDescending(s => s.MaterialStoredId).FirstOrDefault().StockCount    // or .Sum(x => (long)x.StoredCount) /* 이게 맞을듯 하다... */
+            // (x) => x.FmsMaterialStored.Where(s => s.IsApproval == true).OrderByDescending(s => s.MaterialStoredId).FirstOrDefault().StockCount    // or .Sum(x => (long)x.StoredCount) /* 이게 맞을듯 하다... */
+            (x) => x.FmsMaterialStored.Where(s => s.IsApproval == true).Sum(s => (long)s.StoredCount)
                 + (x.FmsMaterialRelease.Where(r => r.IsConfirmed == true && r.AdjustmentTypeId == 2).Sum(r => (long?)r.MaterialCount) ?? 0)
                 - (x.FmsMaterialRelease.Where(r => r.IsConfirmed == true && r.AdjustmentTypeId == 1).Sum(r => (long?)r.MaterialCount) ?? 0)
                 - (x.FmsMaterialRelease.Where(r => r.IsConfirmed == true && r.AdjustmentTypeId == 0).Sum(r => (long?)r.MaterialCount) ?? 0);

+ 4 - 3
QuartzSchedule/Schedulers/WorkScheduler.cs

@@ -2,6 +2,7 @@ using System.Threading.Tasks;
 using Microsoft.Extensions.Logging;
 using Quartz;
 using FMSAdmin.QuartzSchedule.Jobs;
+using System.Collections.Generic;
 
 namespace FMSAdmin.QuartzSchedule.Schedulers {
     public class WorkScheduler {
@@ -22,10 +23,10 @@ namespace FMSAdmin.QuartzSchedule.Schedulers {
                 .WithDescription("매일 0시 작업진행 처리")
                 .Build();
 
-            var trigger = TriggerBuilder
+            var triggerHourly = TriggerBuilder
                 .Create()
                 .StartNow()
-                .WithCronSchedule("1 0 0 * * ?")  // 매일 0시 0분 1초에 실행
+                .WithCronSchedule("1 0 * * * ?")  // 매시 0분 1초에 실행
                 .Build();
 
             // [초 분 시 일 월 요일 연도]
@@ -33,7 +34,7 @@ namespace FMSAdmin.QuartzSchedule.Schedulers {
             // 1 * * * * ?      => 매분 1초
             // 1 0 0 * * ?      => 매일 0시 0분 1초에 실행
 
-            var result = _scheduler.ScheduleJob(jobDetails, trigger);
+            var result = _scheduler.ScheduleJob(jobDetails, triggerHourly);
             return result;
         }
     }

+ 59 - 59
Repositories/App/WorkRequestRepository.cs

@@ -323,43 +323,40 @@ namespace FMSApp.Repositories {
             _logger.LogInformation($"작업시작일이 지나거나 당일인 실행계획 데이터를 작업지시 처리 (처리일 : {DateTime.Now})");
 
             int processCount = 0;
-            using (var trans = new TransactionScope()) {
-                if (_workConfigRepository.IsAutoOrder(true)) {
-                    _logger.LogInformation($"자동지시 전역설정 TRUE");
-                    // 전역설정이 자동지시로 되어있을때는 모든 실행계획 자동지시(정기,법정,교육,수시,공사)
-                    var query = from request in _context.FmsWorkRequest
-                                where request.StartWorkDate <= DateTime.Now.Date
-                                && request.WorkProgressId == 1
-                                && _context.FmsWorkOrder.Where(x => x.SiteId == request.SiteId
-                                                            && x.WorkRequestId == request.WorkRequestId
-                                                            && x.Title == request.Title).Any() == false
-                                select request;
-                    foreach (var request in query) {
-                        WorkToOrder(request.SiteId, request.WorkRequestId, request.RequestUserId, "");
-                        processCount++;
-                    }
-                } else {
-                    _logger.LogInformation($"자동지시 전역설정 FALSE");
-                    // 전역설정이 자동지시로 되어있지 않을때는 정기점검,법정검사,법정교육 (FmsWorkSchedule 등록되어있는 실행계획) 만 자동지시
-                    // 기초계획에 자동지시여부가 true 인것만 자동지시
-                    var query = from schedule in _context.FmsWorkSchedule
-                                join request in _context.FmsWorkRequest on schedule.WorkScheduleId equals request.WorkScheduleId
-                                where schedule.IsUse == true
-                                && request.WorkProgressId == 1
-                                && schedule.IsAutoOrder == true
-                                && (request.StartWorkDate <= DateTime.Now.Date)
-                                && _context.FmsWorkOrder.Where(x => x.SiteId == request.SiteId
-                                                            && x.WorkRequestId == request.WorkRequestId
-                                                            && x.Title == request.Title).Any() == false
-                                select request;
-                    foreach (var request in query) {
-                        WorkToOrder(request.SiteId, request.WorkRequestId, request.RequestUserId, "");
-                        processCount++;
-                    }
+            if (_workConfigRepository.IsAutoOrder(true)) {
+                _logger.LogInformation($"자동지시 전역설정 TRUE");
+                // 전역설정이 자동지시로 되어있을때는 모든 실행계획 자동지시(정기,법정,교육,수시,공사)
+                var query = from request in _context.FmsWorkRequest
+                            where request.StartWorkDate < DateTime.Now.AddDays(1).Date
+                            && request.WorkProgressId == 1
+                            && _context.FmsWorkOrder.Where(x => x.SiteId == request.SiteId
+                                                        && x.WorkRequestId == request.WorkRequestId
+                                                        && x.Title == request.Title).Any() == false
+                            select request;
+                foreach (var request in query.ToList()) {
+                    WorkToOrder(request.SiteId, request.WorkRequestId, request.RequestUserId, "", true);
+                    processCount++;
+                }
+            } else {
+                _logger.LogInformation($"자동지시 전역설정 FALSE");
+                // 전역설정이 자동지시로 되어있지 않을때는 정기점검,법정검사,법정교육 (FmsWorkSchedule 등록되어있는 실행계획) 만 자동지시
+                // 기초계획에 자동지시여부가 true 인것만 자동지시
+                var query = from schedule in _context.FmsWorkSchedule
+                            join request in _context.FmsWorkRequest on schedule.WorkScheduleId equals request.WorkScheduleId
+                            where schedule.IsUse == true
+                            && request.WorkProgressId == 1
+                            && schedule.IsAutoOrder == true
+                            && (request.StartWorkDate < DateTime.Now.AddDays(1).Date)
+                            && _context.FmsWorkOrder.Where(x => x.SiteId == request.SiteId
+                                                        && x.WorkRequestId == request.WorkRequestId
+                                                        && x.Title == request.Title).Any() == false
+                            select request;
+                foreach (var request in query.ToList()) {
+                    WorkToOrder(request.SiteId, request.WorkRequestId, request.RequestUserId, "", true);
+                    processCount++;
                 }
-
-                trans.Complete();
             }
+
             _logger.LogInformation($"처리완료 : {processCount}건");
             _logger.LogInformation($"=============================================================================================");
         }
@@ -370,30 +367,27 @@ namespace FMSApp.Repositories {
             _logger.LogInformation($"작업수행 처리되지 않은 작업대기 목록 자동수행  (처리일시 : {DateTime.Now})");
 
             int processCount = 0;
-            using (var trans = new TransactionScope()) {
-                if (_workConfigRepository.IsAutoResult(true)) {
-                    _logger.LogInformation($"자동수행 전역설정 TRUE");
-                    var query = from order in _context.FmsWorkOrder
-                                join request in _context.FmsWorkRequest on order.WorkRequestId equals request.WorkRequestId
-                                where request.WorkProgressId == 3
-                                    && _context.FmsWorkResult.Where(x => x.SiteId == order.SiteId
-                                                                && x.WorkRequestId == order.WorkRequestId).Any() == false
-                                select order;
-                    foreach (var order in query) {
-                        WorkToResult(order, new FmsWorkResult {
-                            StartDate = order.StartWorkDate.Date,
-                            EndDate = order.StartWorkDate.Date,
-                            Content = "",
-                            WorkerUserId = order.OrderUserId,
-                        });
-                        processCount++;
-                    }
-                } else {
-                    _logger.LogInformation($"자동수행 전역설정 FALSE => 자동수행 안함.");
+            if (_workConfigRepository.IsAutoResult(true)) {
+                _logger.LogInformation($"자동수행 전역설정 TRUE");
+                var query = from order in _context.FmsWorkOrder
+                            join request in _context.FmsWorkRequest on order.WorkRequestId equals request.WorkRequestId
+                            where request.WorkProgressId == 3
+                                && _context.FmsWorkResult.Where(x => x.SiteId == order.SiteId
+                                                            && x.WorkRequestId == order.WorkRequestId).Any() == false
+                            select order;
+                foreach (var order in query.ToList()) {
+                    WorkToResult(order, new FmsWorkResult {
+                        StartDate = order.StartWorkDate.Date,
+                        EndDate = order.StartWorkDate.Date,
+                        Content = "",
+                        WorkerUserId = order.OrderUserId,
+                    }, true);
+                    processCount++;
                 }
-
-                trans.Complete();
+            } else {
+                _logger.LogInformation($"자동수행 전역설정 FALSE => 자동수행 안함.");
             }
+
             _logger.LogInformation($"처리완료 : {processCount}건");
             _logger.LogInformation($"=============================================================================================");
         }
@@ -444,7 +438,7 @@ namespace FMSApp.Repositories {
                 _context.SaveChanges();
 
                 // 신규 WorkOrderToFacility 생성 From FmsWorkRequestToFacility
-                foreach (var facility in persist.FmsWorkRequestToFacility) {
+                foreach (var facility in persist.FmsWorkRequestToFacility.ToList()) {
                     _context.FmsWorkOrderToFacility.Add(new FmsWorkOrderToFacility() {
                         SiteId = facility.SiteId,
                         WorkRequestId = facility.WorkRequestId,
@@ -464,6 +458,9 @@ namespace FMSApp.Repositories {
                 }
 
                 if (trans != null) trans.Complete();
+            } catch (Exception ex) {
+                _logger.LogError(ex, "");
+                throw ex;
             } finally {
                 if (trans != null) trans.Dispose();
             }
@@ -509,7 +506,7 @@ namespace FMSApp.Repositories {
                 _context.SaveChanges();
 
                 // 신규 FmsWorkResultToFacility 생성 From FmsWorkOrderToFacility
-                foreach (var facility in order.FmsWorkOrderToFacility) {
+                foreach (var facility in order.FmsWorkOrderToFacility.ToList()) {
                     _context.FmsWorkResultToFacility.Add(new FmsWorkResultToFacility() {
                         SiteId = facility.SiteId,
                         WorkRequestId = facility.WorkRequestId,
@@ -519,6 +516,9 @@ namespace FMSApp.Repositories {
                 _context.SaveChanges();
 
                 if (trans != null) trans.Complete();
+            } catch (Exception ex) {
+                _logger.LogError(ex, "");
+                throw ex;
             } finally {
                 if (trans != null) trans.Dispose();
             }

+ 4 - 0
Services/AnnouncementService.cs

@@ -107,6 +107,10 @@ namespace FMSAdmin.Services {
                 if (data.CmFile != null && data.CmFile.IsUpload) {
                     persist.CmFile = data.CmFile;
                 }
+                if (data.CmFile != null && data.CmFile.IsDelete) {
+                    persist.CmFile = null;
+                    persist.FileId = null;
+                }
                 _context.CmAnnouncement.Update(persist);
                 _context.SaveChanges();
 

+ 20 - 1
Services/App/MaterialService.cs

@@ -29,6 +29,7 @@ namespace FMSApp.Services {
 
         public void Create(FmsMaterial data) {
             using (var trans = new TransactionScope()) {
+                checkName(data);
                 if (data.CmFile != null && data.CmFile.IsUpload) {
                     data.CmFile.SiteId = data.SiteId;
                     var category = _context.CmFileCategory.First(x => x.Name == "material");
@@ -50,6 +51,14 @@ namespace FMSApp.Services {
             }
         }
 
+
+        public int checkName(FmsMaterial data, bool isExcel = false) {
+            var check = _context.FmsMaterial.Where(x => x.SiteId == data.SiteId && x.BusinessFieldId == data.BusinessFieldId && x.Name == data.Name && x.Standard == data.Standard).Count();
+            if (!isExcel && check > 0) {
+                throw new ServiceException("동일 정보가 존재합니다. [업무분야-자재명-규격]");
+            }
+            return check;
+        }
         public void Edit(int id, int siteId, FmsMaterial data) {
             using (var trans = new TransactionScope()) {
                 if (data.CmFile != null && data.CmFile.IsUpload) {
@@ -67,6 +76,16 @@ namespace FMSApp.Services {
                     throw new ServiceException("정보를 찾을 수 없습니다.");
                 }
 
+                if (!persist.BusinessFieldId.Equals(data.BusinessFieldId)) {
+                    checkName(data);
+                }
+                if (!persist.Name.Equals(data.Name)) {
+                    checkName(data);
+                }
+                if (!Util.IsNullOrEmpty(data.Standard)) {
+                    if (!persist.Standard.Equals(data.Standard))
+                        checkName(data);
+                }
                 persist.SiteId = data.SiteId;
                 persist.BusinessFieldId = data.BusinessFieldId;
                 persist.Name = data.Name;
@@ -78,7 +97,7 @@ namespace FMSApp.Services {
                 persist.MaterialCode = data.MaterialCode;
                 persist.Unit = data.Unit;
                 persist.DurableYears = data.DurableYears;
-                persist.Rfid = data.Rfid;
+                //persist.Rfid = data.Rfid;
                 persist.Manufacturer = data.Manufacturer;
                 persist.FinalPrice = data.FinalPrice;
                 persist.ReasonableStockCount = data.ReasonableStockCount;

+ 2 - 0
Services/App/UserService.cs

@@ -97,6 +97,8 @@ namespace FMSApp.Services {
                     _context.SaveChanges();
 
                 } else {
+                    if (emp.EmploymentStatus == EmploymentStatus.퇴직)
+                        throw new ServiceException("로그인 할 수 없습니다.");
                     throw new ServiceException("아이디나 비밀번호가 잘못되었습니다.");
                 }
             } catch (Exception ex) {

+ 4 - 0
Services/CertificateStatusService.cs

@@ -93,6 +93,10 @@ namespace FMSAdmin.Services {
                 persist.SiteId = data.SiteId;
                 persist.UpdateDate = DateTime.Now;
 
+                if (data.CmFile2 != null && data.CmFile2.IsDelete) {
+                    persist.CmFile2 = null;
+                    persist.FileId2 = null;
+                }
                 _context.CmCertificateStatus.Update(persist);
                 _context.SaveChanges();
 

+ 4 - 1
Services/ContractManagementService.cs

@@ -111,7 +111,10 @@ namespace FMSAdmin.Services {
                 if (data.CmFile != null && data.CmFile.IsUpload) {
                     persist.CmFile = data.CmFile;
                 }
-
+                if (data.CmFile != null && data.CmFile.IsDelete) {
+                    persist.CmFile = null;
+                    persist.FileId = null;
+                }
                 _context.FmsContract.Update(persist);
                 _context.SaveChanges();
 

+ 6 - 0
Services/EnergyDayAnalysisService.cs

@@ -179,9 +179,15 @@ namespace FMSAdmin.Services {
             var persist = _context.FmsEnergyAnalysis
                             .Where(x => x.SiteId == siteId && x.FuelTypeId == fuelTypeId && x.FuelPriceId == fuelPriceId && x.Year == year && x.Month == month && x.PriceTypeId == priceTypeId).FirstOrDefault();
             if (persist == null) {
+                data.PriceTypeId = priceTypeId;
+                data.Year = year;
+                data.Month = month;
                 _context.FmsEnergyAnalysis.Add(data);
                 _context.SaveChanges();
             } else {
+                persist.PriceTypeId = priceTypeId;
+                persist.Year = year;
+                persist.Month = month;
                 persist.Content = data.Content;
                 _context.FmsEnergyAnalysis.Update(persist);
                 _context.SaveChanges();

+ 4 - 0
Services/GuidelineService.cs

@@ -106,6 +106,10 @@ namespace FMSAdmin.Services {
                 if (data.CmFile != null && data.CmFile.IsUpload) {
                     persist.CmFile = data.CmFile;
                 }
+                if (data.CmFile != null && data.CmFile.IsDelete) {
+                    persist.CmFile = null;
+                    persist.FileId = null;
+                }
                 _context.CmGuideline.Update(persist);
                 _context.SaveChanges();
 

+ 4 - 1
Services/LayoutService.cs

@@ -91,7 +91,10 @@ namespace FMSAdmin.Services {
                 persist.Month = data.Month;
                 persist.SiteId = data.SiteId;
                 persist.UpdateDate = DateTime.Now;
-
+                if (data.CmFile2 != null && data.CmFile2.IsDelete) {
+                    persist.CmFile2 = null;
+                    persist.FileId2 = null;
+                }
                 _context.CmLayout.Update(persist);
                 _context.SaveChanges();
 

+ 8 - 5
Services/MaterialService.cs

@@ -52,7 +52,8 @@ namespace FMSAdmin.Services {
         public void Create(FmsMaterial data) {
             using (var trans = new TransactionScope()) {
                 checkName(data);
-                if (!Util.IsNullOrEmpty(data.Rfid)) checkRfid(data);
+                //현대해상 자재qr코드 숨김처리 
+                //if (!Util.IsNullOrEmpty(data.Rfid)) checkRfid(data);
 
                 if (data.CmFile != null && data.CmFile.IsUpload) {
                     data.CmFile.SiteId = data.SiteId;
@@ -102,9 +103,10 @@ namespace FMSAdmin.Services {
                     if (!persist.Standard.Equals(data.Standard))
                         checkName(data);
                 }
-                if (!Util.IsNullOrEmpty(data.Rfid)) {
-                    if (!persist.Rfid.Equals(data.Rfid)) checkRfid(data);
-                }
+                //현대해상 자재qr코드 숨김처리 
+                // if (!Util.IsNullOrEmpty(data.Rfid)) {
+                //     if (!persist.Rfid.Equals(data.Rfid)) checkRfid(data);
+                // }
 
                 persist.SiteId = data.SiteId;
                 persist.BusinessFieldId = data.BusinessFieldId;
@@ -119,7 +121,8 @@ namespace FMSAdmin.Services {
                 persist.MaterialCode = data.MaterialCode;
                 persist.Unit = data.Unit;
                 persist.DurableYears = data.DurableYears;
-                persist.Rfid = data.Rfid;
+                //현대해상 자재qr코드 숨김처리 
+                //persist.Rfid = data.Rfid;
                 persist.Manufacturer = data.Manufacturer;
                 persist.FinalPrice = data.FinalPrice;
                 persist.ReasonableStockCount = data.ReasonableStockCount;

+ 2 - 4
Services/MaterialStockService.cs

@@ -231,8 +231,7 @@ namespace FMSAdmin.Services {
                                LastStockCount = _context.FmsMaterialStored
                                                 .Where(x => x.StoredDate.Date <= g.Key.Date && x.MaterialId == g.Key.MaterialId && x.IsApproval == true)
                                                 .OrderByDescending(x => x.StoredDate)
-                                                .Select(x => x.StockCount)
-                                                .FirstOrDefault(),
+                                                .Sum(x => x.StoredCount),
                                LastStockDate = _context.FmsMaterialStored
                                                 .Where(x => x.StoredDate.Date <= g.Key.Date && x.MaterialId == g.Key.MaterialId && x.IsApproval == true)
                                                 .OrderByDescending(x => x.StoredDate)
@@ -319,8 +318,7 @@ namespace FMSAdmin.Services {
                                LastStockCount = _context.FmsMaterialStored
                                                 .Where(x => x.StoredDate.Date <= g.Max(x => x.Date).Date && x.MaterialId == g.Key.MaterialId && x.IsApproval == true)
                                                 .OrderByDescending(x => x.StoredDate)
-                                                .Select(x => x.StockCount)
-                                                .FirstOrDefault(),
+                                                .Sum(x => x.StoredCount),
                                LastStockDate = _context.FmsMaterialStored
                                                 .Where(x => x.StoredDate.Date <= g.Max(x => x.Date).Date && x.MaterialId == g.Key.MaterialId && x.IsApproval == true)
                                                 .OrderByDescending(x => x.StoredDate)

+ 4 - 1
Services/OrganizationChartStatusService.cs

@@ -88,7 +88,10 @@ namespace FMSAdmin.Services {
                     data.CmFile2.CreatedDate = DateTime.Now;
                     persist.CmFile2 = data.CmFile2;
                 }
-
+                if (data.CmFile2 != null && data.CmFile2.IsDelete) {
+                    persist.CmFile2 = null;
+                    persist.FileId2 = null;
+                }
                 persist.Year = data.Year;
                 persist.Month = data.Month;
                 persist.SiteId = data.SiteId;

+ 4 - 1
Services/RentalStatusService.cs

@@ -91,7 +91,10 @@ namespace FMSAdmin.Services {
                 persist.Month = data.Month;
                 persist.SiteId = data.SiteId;
                 persist.UpdateDate = DateTime.Now;
-
+                if (data.CmFile2 != null && data.CmFile2.IsDelete) {
+                    persist.CmFile2 = null;
+                    persist.FileId2 = null;
+                }
                 _context.CmRentalStatus.Update(persist);
                 _context.SaveChanges();
 

+ 3 - 2
Services/SiteWeatherInfoService.cs

@@ -248,11 +248,12 @@ SELECT Sido AS [시도], Sigun AS [구군], [00],[01],[02],[03],[04],[05],[06],[
 
             var sidoName = WebUtility.UrlDecode(sido);
 
-            var forecast = $"http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/getCtprvnMesureSidoLIst?serviceKey={_appSettings.DustApiKey}&numOfRows=100&pageNo=1&sidoName={sidoName}&searchCondition=HOUR";
+            //var forecast = $"http://openapi.airkorea.or.kr/openapi/services/rest/ArpltnInforInqireSvc/getCtprvnMesureSidoLIst?serviceKey={_appSettings.DustApiKey}&numOfRows=100&pageNo=1&sidoName={sidoName}&searchCondition=HOUR";
+            var forecast = $"http://apis.data.go.kr/B552584/ArpltnStatsSvc/getCtprvnMesureSidoLIst?serviceKey={_appSettings.DustApiKey}&numOfRows=100&pageNo=1&sidoName={sidoName}&searchCondition=HOUR";
 
             string content = null;
             content = pullUrl(forecast);
-            //_logger.LogInformation(content);
+            // _logger.LogInformation(content);
 
             XElement xml = XElement.Parse(content);
 

+ 4 - 0
Services/SurveyService.cs

@@ -94,6 +94,10 @@ namespace FMSAdmin.Services {
                 persist.IsAllView = data.IsAllView;
                 persist.UpdateDate = DateTime.Now;
 
+                if (data.CmFile2 != null && data.CmFile2.IsDelete) {
+                    persist.CmFile2 = null;
+                    persist.FileId2 = null;
+                }
                 _context.CmSurvey.Update(persist);
                 _context.SaveChanges();
 

+ 3 - 2
Services/UserService.cs

@@ -277,9 +277,10 @@ namespace FMSAdmin.Services {
             }
         }
 
-        public void ChangePassword(int siteId, string id, string password) {
+        public void ChangePassword(int siteId, string id, string password, bool bInit = false) {
             var data = _context.CmUser.First(x => x.UserId == id && x.SiteId == siteId);
-            if (data.Passwd == password) {
+            if (!bInit && data.Passwd == password) {
+                //패스워드 초기화가 아닌 경우만 기존 패스워드 체크.
                 throw new ServiceException("기존 패스워드와 동일한 패스워드를 사용할 수 없습니다.");
             }
             data.Passwd = password;

+ 87 - 0
Services/WorkBaseService.cs

@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+using System.Security.Claims;
+using System.Text;
+using System.Transactions;
+
+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 FMSApp.Repositories;
+
+namespace FMSAdmin.Services {
+    public class WorkBaseService {
+        private readonly ILogger<WorkBaseService> _logger;
+        private readonly FMSContext _context;
+        private readonly WorkRequestRepository _workRequestRepository;
+        private readonly WorkConfigRepository _workConfigRepository;
+
+        public WorkBaseService(
+            ILogger<WorkBaseService> logger,
+            FMSContext context,
+            WorkRequestRepository workRequestRepository,
+            WorkConfigRepository workConfigRepository) {
+            _logger = logger;
+            _context = context;
+            _workRequestRepository = workRequestRepository;
+            _workConfigRepository = workConfigRepository;
+        }
+
+        public void ImportExcel(IList<FmsWorkRequest> list, string userId) {
+            // using (var trans = new TransactionScope()) {
+            foreach (var item in list) {
+                // FmsWorkRequest INSERT
+                _context.FmsWorkRequest.Add(item);
+                _context.SaveChanges();
+
+                // FmsWorkOrder INSERT
+                _workRequestRepository.WorkToOrder(item.SiteId, item.WorkRequestId, item.RequestUserId, item.Content, false);
+
+                // FmsWorkResult INSERT
+                if (!_workConfigRepository.IsAutoResult(true)) {
+                    var order = _context.FmsWorkOrder.FirstOrDefault(
+                        x => x.SiteId == item.SiteId
+                        && x.WorkRequestId == item.WorkRequestId
+                    );
+                    // order.FmsWorkRequest.WorkProgressId = 3;
+                    _workRequestRepository.WorkToResult(order, new FmsWorkResult() {
+                        StartDate = item.StartWorkDate.Date,
+                        EndDate = item.StartWorkDate.Date,
+                        Content = "",
+                        WorkerUserId = item.RequestUserId,
+                    });
+                }
+
+                var result = _context.FmsWorkResult.FirstOrDefault(
+                    x => x.SiteId == item.SiteId
+                    && x.WorkRequestId == item.WorkRequestId
+                );
+                result.IsConfirmed = true;
+                result.ConfirmedUserId = item.RequestUserId;
+                result.WorkerUserId = item.RequestUserId;
+                result.ConfirmedDate = item.RequestDate;
+                _context.FmsWorkResult.Update(result);
+                _context.SaveChanges();
+
+                // FmsWorkRequest UPDATE
+                var request = _context.FmsWorkRequest.FirstOrDefault(
+                    x => x.SiteId == item.SiteId
+                    && x.WorkRequestId == item.WorkRequestId
+                );
+                request.WorkProgressId = 6;
+                _context.FmsWorkRequest.Update(request);
+                _context.SaveChanges();
+            }
+
+            //     trans.Complete();
+            // }
+        }
+    }
+}

+ 2 - 2
appsettings.Development.json.example

@@ -5,8 +5,8 @@
     "StorageUrl": "http://localhost:9090",
     "SiteUrl": "http://localhost:9090",
     "Scheduler": "off",
-    "WeatherApiKey": "L2tohxvq9Ro8DU%2BaVOGpY9%2B0EbVxL4HRHCwEAeiUYTRUNegytTdOFPN2W%2FxpTo0%2BeEQE%2FGY85zp5LTEe6n6g0A%3D%3D",
-    "DustApiKey": "L2tohxvq9Ro8DU%2BaVOGpY9%2B0EbVxL4HRHCwEAeiUYTRUNegytTdOFPN2W%2FxpTo0%2BeEQE%2FGY85zp5LTEe6n6g0A%3D%3D"
+    "WeatherApiKey": "%2Fb1uV%2FBf0ckaHJhP5IMVIBkxVSAB%2F9aixZVSgj0%2BJkpvFZMXUDDD4B16uEFdeM1wnm4iFGc97ghjWZ9oBwsTSQ%3D%3D",
+    "DustApiKey": "%2Fb1uV%2FBf0ckaHJhP5IMVIBkxVSAB%2F9aixZVSgj0%2BJkpvFZMXUDDD4B16uEFdeM1wnm4iFGc97ghjWZ9oBwsTSQ%3D%3D"
   },
   "AllowedHosts": "*",
   "ConnectionStrings": {

+ 2 - 2
appsettings.json.example

@@ -4,8 +4,8 @@
     "StoragePath": "/react/fms-admin-backend",
     "StorageUrl": "http://localhost:9090",
     "SiteUrl": "http://localhost:9090",
-    "WeatherApiKey": "L2tohxvq9Ro8DU%2BaVOGpY9%2B0EbVxL4HRHCwEAeiUYTRUNegytTdOFPN2W%2FxpTo0%2BeEQE%2FGY85zp5LTEe6n6g0A%3D%3D",
-    "DustApiKey": "L2tohxvq9Ro8DU%2BaVOGpY9%2B0EbVxL4HRHCwEAeiUYTRUNegytTdOFPN2W%2FxpTo0%2BeEQE%2FGY85zp5LTEe6n6g0A%3D%3D"
+    "WeatherApiKey": "N50NNBTbuys7Gx9rkx3avyMCjEbP0IG8VaP5Ud4%2BtjKPapN22CX9xFFnYf5F9y%2BV0cBNMZRF8OY9V%2Fgs6K8pyA%3D%3D",
+    "DustApiKey": "N50NNBTbuys7Gx9rkx3avyMCjEbP0IG8VaP5Ud4%2BtjKPapN22CX9xFFnYf5F9y%2BV0cBNMZRF8OY9V%2Fgs6K8pyA%3D%3D"
   },
   "Serilog": {
     "MinimumLevel": {