using System;
using System.Linq;
using System.Threading.Tasks;

using FMSAdmin.Data;
using FMSAdmin.Models;
using FMSAdmin.Entities;
using FMSApp.Services;
using FMSAdmin.Services;

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authorization;
using FMSAdmin.Helpers;
using System.Data;
using System.IO;
using OfficeOpenXml;
using System.Collections.Generic;
using LinqKit;

namespace FMSAdmin.Controllers {
    [Authorize]
    [ApiController]
    [ApiVersion("1")]
    [Route("api/[controller]")]
    public class WorkResultController : Controller {
        private readonly ILogger<WorkResultController> _logger;
        private readonly FMSContext _context;
        private readonly WorkResultService _service;
        private readonly WorkScheduleService _scheduleService;
        private readonly WorkResultToFacilityService _service_2;
        private readonly WorkRequestService _requestService;
        private readonly MonthWorkService _monthWorkService;

        private readonly WeekWorkService _weekWorkService;
        private readonly StorageHelper _storage;

        public WorkResultController(
            ILogger<WorkResultController> logger,
            FMSContext context,
            WorkResultService service,
            WorkResultToFacilityService service_2,
            WorkRequestService requestService,
            WorkScheduleService scheduleService,
            MonthWorkService monthWorkService,
            WeekWorkService weekWorkService,
            StorageHelper storage
            ) {
            _logger = logger;
            _context = context;
            _service = service;
            _service_2 = service_2;
            _scheduleService = scheduleService;
            _requestService = requestService;
            _storage = storage;
            _monthWorkService = monthWorkService;
            _weekWorkService = weekWorkService;
        }

        //작업진행 필터
        //엑셀하고 같은 조건을 사용하기위해 분리함
        public IQueryable<FmsWorkResult> _Filter([FromQuery] PagingRequest req, [FromQuery] string workProgressId, [FromQuery] string facilityCode) {
            int nWorkProgressId = 0;
            int.TryParse(workProgressId, out nWorkProgressId);

            if (nWorkProgressId != 2 && nWorkProgressId != 4 && nWorkProgressId != 5 && nWorkProgressId != 9 && nWorkProgressId != 10 && nWorkProgressId != 11 && nWorkProgressId != 99) {
                throw new ServiceException("입력 파라메터가 잘못되었습니다.");
            }

            var query = _FilterAndSort(req);
            if (nWorkProgressId == 4) {
                // 작업진행 목록에서는 작업진행(4), 작업보류(7) 데이터를 조회
                query = query.Where(x => new int[] { 4, 7 }.Contains(x.FmsWorkRequest.WorkProgressId));
            }
            if (nWorkProgressId == 5) {
                // 작업완료 목록에서는 작업완료(5) 데이터를 조회
                query = query.Where(x => x.FmsWorkRequest.WorkProgressId == 5);
            }
            if (nWorkProgressId == 2) {
                // 작업 반려 목록에서는 작업반려(2) 데이터를 조회
                query = query.Where(x => x.FmsWorkRequest.WorkProgressId == 2);
            }


            if (nWorkProgressId == 9) {
                // New 작업완료(작업진행, 작업완료)
                query = query.Where(x => new int[] { 4, 5, 7 }.Contains(x.FmsWorkRequest.WorkProgressId));
            }

            if (nWorkProgressId == 10) {
                // 업무별 작업 현황 (월별 )

                var startDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                var endDate = startDate.AddMonths(1).AddDays(-1);

                query = query.Where(x => x.FmsWorkRequest.WorkProgressId == 4);
                query = query.Where(x => (x.EndDate.Date >= startDate && x.StartDate.Date <= endDate));

            }
            if (nWorkProgressId == 11) {
                // 업무별 작업 현황 (월별 )

                var startDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
                var endDate = startDate.AddMonths(1).AddDays(-1);

                query = query.Where(x => x.FmsWorkRequest.WorkProgressId == 5);
                query = query.Where(x => (x.EndDate.Date >= startDate && x.StartDate.Date <= endDate));

            }

            if (facilityCode != null) {
                // var reqId = _context.FmsWorkResultToFacility.Where(x => x.FacilityCode == Util.ToInt( facilityCode)).orderby;
                query = query.Where(x =>
                x.FmsWorkResultToFacility.Where(f =>
                // f.SiteId == x.SiteId
                // && f.WorkRequestId == x.WorkRequestId
                f.FacilityCode == Util.ToInt(facilityCode)).Count() > 0);
            }
            return query;
        }

        /// <summary>
        /// 목록
        /// </summary>
        [HttpGet]
        public IActionResult List([FromQuery] PagingRequest req, [FromQuery] string workProgressId, [FromQuery] string facilityCode) {
            var query = _Filter(req, workProgressId, facilityCode);
            var list = _ListSelect(query);
            //_logger.LogInformation("query", query);
            var paging = PagingList.Pagination(list, req.page, req.limit);
            return Ok(paging);
        }

        /// <summary>
        /// 작업진행목록 / 작업완료목록 조회
        /// </summary>
        [HttpGet]
        private dynamic _ListSelect(IQueryable<FmsWorkResult> query) {

            var list = query.Select(x => new {
                x.SiteId,
                SiteName = x.FmsWorkRequest.Site.Name,
                x.WorkRequestId,
                BusinessFieldId = x.FmsWorkOrder.BusinessFieldId,
                BusinessFieldName = x.FmsWorkOrder.CmBusinessField.Name,
                WorkTypeId = x.FmsWorkRequest.WorkTypeId,
                WorkTypeName = x.FmsWorkRequest.WorkType.Name,
                StartDate = x.StartDate.ToString("yyyy-MM-dd"),
                EndDate = x.EndDate.ToString("yyyy-MM-dd"),
                Title = x.FmsWorkOrder.Title,
                WorkProgressId = x.FmsWorkRequest.WorkProgressId,
                WorkProgressName = x.FmsWorkRequest.WorkProgress.Name,
                WorkerUserId = x.WorkerUserId,
                WorkerUserName = x.CmUserNavigation.Name,
                x.Content,
                OrderContent = x.FmsWorkOrder.Content,
                RequestContent = x.FmsWorkRequest.Content,
                OrderDate = x.FmsWorkOrder.OrderDate.ToString("yyyy-MM-dd"),
                //x.AddDate != null ? x.AddDate.Value.ToString("yyyy/MM/dd") : null,
                StartWorkDate = x.FmsWorkOrder.StartWorkDate.ToString("yyyy-MM-dd"),
                OrderUserId = x.FmsWorkOrder.OrderUserId,
                RequestUserName = x.FmsWorkRequest.CmUserNavigation.Name,
                RejectUserName = x.FmsWorkRequest.CmUser.Name,
                //RejectReason=x.FmsWorkRequest.RejectReason,
                OrderUserName = x.FmsWorkOrder.CmUser.Name,

                x.IsConfirmed,
                x.ConfirmedUserId,
                ConfirmedUserName = x.CmUser.Name,
                WorkPartnerName = x.FmsWorkRequest.WorkPartner.Name,
                WorkPrice = x.FmsWorkRequest.WorkPrice
            });

            return list;
        }
        /// <summary>
        /// 작업진행 내역_엑셀파일 익스포트
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpGet("WorkExcel")]
        public IActionResult WorkExcel([FromQuery] PagingRequest req, [FromQuery] string workProgressId, [FromQuery] string facilityCode, string filename) {
            req.page = 1;
            req.limit = 0;
            var query = _Filter(req, workProgressId, facilityCode);
            var list = _ListSelect(query);
            var stream = new MemoryStream();
            using (var package = new ExcelPackage(stream)) {
                var workSheet = package.Workbook.Worksheets.Add("Sheet1");

                workSheet.Cells.LoadFromCollection(list, true);

                if (req.columns != null && req.columns.Length > 0) {
                    workSheet.AddStyle(req.columns, req.sort?.order?.ToLower() == "asc", filename);
                }
                package.Save();
            }
            stream.Position = 0;
            string excelName = $"excel-{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xlsx";
            return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", excelName);
        }


        /// <summary>
        /// 설비별 작업 승이 내역_엑셀파일 익스포트
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpGet("excel")]
        public IActionResult ExportExcel([FromQuery] PagingRequest req, string filename) {
            req.page = 1;
            req.limit = 0;
            //var query = _FilterAndSort(req);

            //var list = _ListSelect(query);
            var query = _FilterAndSort_2(req);
            query = query.Where(x => x.FmsWorkResult.IsConfirmed);


            var list = query.Select(x => new {
                x.SiteId,
                Site = x.FmsWorkResult.FmsWorkRequest.Site.Name,
                //x.WorkRequestId,
                //x.FacilityCode,
                //BusinessFieldName = x.FmsWorkResult.FmsWorkRequest.CmBusinessField.Name,
                WorkType = x.FmsWorkResult.FmsWorkRequest.WorkType.Name,
                StartDate = x.FmsWorkResult.StartDate.ToString("yyyy-MM-dd"),
                EndDate = x.FmsWorkResult.EndDate.ToString("yyyy-MM-dd"),
                FirstClassName = x.CmFacility.FmsFacilityCodeClass.Name,
                SecondClassName = x.CmFacility.FmsFacilityCodeClass1.Name,
                ThirdClassName = x.CmFacility.FmsFacilityCodeClass2.Name,
                FacilityName = x.CmFacility.Name,
                Title = x.FmsWorkResult.FmsWorkOrder.Title
            });

            var stream = new MemoryStream();
            using (var package = new ExcelPackage(stream)) {
                var workSheet = package.Workbook.Worksheets.Add("Sheet1");

                workSheet.Cells.LoadFromCollection(list, true);

                if (req.columns != null && req.columns.Length > 0) {
                    workSheet.AddStyle(req.columns, req.sort?.order?.ToLower() == "asc", filename);
                }
                package.Save();
            }
            stream.Position = 0;
            string excelName = $"excel-{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xlsx";
            return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", excelName);
        }

        /// <summary>
        /// 작업 이력 내역_엑셀파일 익스포트
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        [HttpGet("WorkHistoryExcel")]
        public IActionResult WorkHistoryExcel([FromQuery] PagingRequest req, [FromQuery] string facilityCode, [FromQuery] int? workProgressId, string filename) {
            req.page = 1;
            req.limit = 0;

            var query = _FilterAndSort(req);


            if (facilityCode != null) {
                query = query.Where(x =>
                x.FmsWorkResultToFacility.Where(f =>
                f.FacilityCode == Util.ToInt(facilityCode)).Count() > 0);
            }
            if (workProgressId != null) {
                query = query.Where(x => x.FmsWorkRequest.WorkProgressId == workProgressId);

            }



            var list = query.Select(x => new {
                x.SiteId,
                SiteName = x.FmsWorkRequest.Site.Name,
                BusinessFieldName = x.FmsWorkRequest.CmBusinessField.Name,
                WorkTypeName = x.FmsWorkRequest.WorkType.Name,
                StartDate = x.StartDate.ToString("yyyy-MM-dd"),
                EndDate = x.EndDate.ToString("yyyy-MM-dd"),
                Title = x.FmsWorkOrder.Title,
                WorkProgressName = x.FmsWorkRequest.WorkProgress.Name,
                RequestUserName = x.FmsWorkRequest.CmUserNavigation.Name,
                WorkerUserName = x.CmUserNavigation.Name,
                ConfirmedUserName = x.CmUser.Name,

            });

            var stream = new MemoryStream();
            using (var package = new ExcelPackage(stream)) {
                var workSheet = package.Workbook.Worksheets.Add("Sheet1");

                workSheet.Cells.LoadFromCollection(list, true);

                if (req.columns != null && req.columns.Length > 0) {
                    workSheet.AddStyle(req.columns, req.sort?.order?.ToLower() == "asc", filename);
                }
                package.Save();
            }
            stream.Position = 0;
            string excelName = $"excel-{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xlsx";
            return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", excelName);
        }

        /// <summary>
        /// 작업진행달력
        /// </summary>
        [HttpGet("[action]")]
        public IActionResult CalendarList([FromQuery] PagingRequest req, [FromQuery] string siteId, [FromQuery] int year, [FromQuery] int month, bool businessAuth) {
            DateTime target = new DateTime(year, month, 1);
            DateTime start = target.AddMonths(-1);
            DateTime end = target.AddMonths(2).AddDays(-1);

            var query = _FilterAndSort(req);
            query = BusinessFieldHelper.Apply<FmsWorkResult>(_context, User, businessAuth, query, "FmsWorkOrder");
            query = query.Where(
                x => x.SiteId == Util.ToInt(siteId)
                && (new int[] { 4, 7 }).Contains(x.FmsWorkRequest.WorkProgressId)
                && x.StartDate <= end
                && x.EndDate >= start
            );
            var list = query.Select(x => new {
                x.SiteId,
                x.WorkRequestId,
                x.FmsWorkRequest.WorkProgressId,
                WorkProgress = new {
                    x.FmsWorkRequest.WorkProgress.Name
                },
                x.FmsWorkRequest.WorkTypeId,
                WorkTypeName = x.FmsWorkRequest.WorkType.Name,
                x.FmsWorkOrder.BusinessFieldId,
                BusinessField = new {
                    x.FmsWorkOrder.CmBusinessField.Name
                },
                x.FmsWorkOrder.Title,
                x.Content,
                OrderContent = x.FmsWorkOrder.Content,
                RequestContent = x.FmsWorkRequest.Content,
                x.StartDate,
                x.EndDate,
                x.FmsWorkOrder.OrderDate,
                x.FmsWorkOrder.StartWorkDate,
                x.FmsWorkOrder.OrderUserId,
                OrderUser = new {
                    x.FmsWorkOrder.CmUser.Name
                },
                x.WorkerUserId,
                WorkerUser = new {
                    x.CmUserNavigation.Name
                },
                x.IsConfirmed,
                x.ConfirmedUserId,
                ConfirmedUser = new {
                    x.CmUser.Name
                },
            });
            return Ok(list);
        }

        /// <summary>
        /// 항목조회
        /// </summary>
        [HttpGet("[action]")]
        public IActionResult Get([FromQuery] string siteId, [FromQuery] string workRequestId) {
            var query = _service.GetAll()
                .Where(x => x.SiteId == Util.ToInt(siteId) && x.WorkRequestId == Util.ToInt(workRequestId));
            var item = query.Select(x => new {
                x.SiteId,
                CmSite = new {
                    x.FmsWorkRequest.Site.Name
                },
                x.WorkRequestId,
                x.FmsWorkRequest.WorkScheduleId,
                x.FmsWorkRequest.WorkProgressId,
                WorkProgress = new {
                    x.FmsWorkRequest.WorkProgress.Name,
                    x.FmsWorkRequest.WorkProgress.WorkProgressId,
                },
                x.FmsWorkRequest.WorkTypeId,
                WorkType = new {
                    x.FmsWorkRequest.WorkType.Name
                },
                x.FmsWorkOrder.BusinessFieldId,
                BusinessField = new {
                    x.FmsWorkOrder.CmBusinessField.Name
                },
                x.FmsWorkOrder.Title,
                x.Content,
                FmsWorkOrder = new {
                    x.FmsWorkOrder.Content,
                },
                FmsWorkRequest = new {
                    x.FmsWorkRequest.Content,
                    x.FmsWorkRequest.WorkUsers,
                    x.FmsWorkRequest.StartWorkDate,
                },
                x.StartDate,
                x.EndDate,
                x.FmsWorkOrder.OrderDate,
                x.FmsWorkOrder.StartWorkDate,
                WorkDueDate = (x.FmsWorkRequest.FmsWorkSchedule == null ? x.FmsWorkRequest.StartWorkDate : x.FmsWorkRequest.FmsWorkSchedule.WorkDueDate),
                x.FmsWorkOrder.OrderUserId,
                OrderUser = new {
                    x.FmsWorkOrder.CmUser.Name
                },
                x.WorkerUserId,
                WorkerUser = new {
                    x.CmUserNavigation.Name
                },
                x.IsConfirmed,
                x.ConfirmedUserId,
                ConfirmedUser = new {
                    x.CmUser.Name
                },
                x.ConfirmDesc,
                RejectReason = x.FmsWorkRequest.RejectReason,

                WorkPartner = new {
                    x.FmsWorkRequest.WorkPartner.Name,
                    x.FmsWorkRequest.WorkPartner.PartnerId
                },
                WorkPrice = x.FmsWorkRequest.WorkPrice,
                WorkItem = x.FmsWorkRequest.WorkItem,
                WorkEndDate = x.FmsWorkRequest.WorkEndDate,
                WorkDetailType = new {
                    x.FmsWorkRequest.WorkDetailType.Code,
                    x.FmsWorkRequest.WorkDetailType.Name,
                },
                CmFile = _storage.ParseFile(x.FmsWorkRequest.CmFile),
                FmsWorkResultToFacility = x.FmsWorkResultToFacility.Select(f => new {
                    f.SiteId,
                    f.WorkRequestId,
                    f.FacilityCode,
                    CmFacility = new {
                        f.CmFacility.Name,
                        f.CmFacility.BuildingId,
                        CmBuilding = new {
                            f.CmFacility.CmBuilding.Name,
                        },
                        f.CmFacility.FloorId,
                        CmFloor = new {
                            f.CmFacility.CmFloor.Name,
                        },
                        f.CmFacility.FirstClassId,
                        FirstClass = new {
                            f.CmFacility.FmsFacilityCodeClass.Name,
                        },
                        f.CmFacility.SecondClassId,
                        SecondClass = new {
                            f.CmFacility.FmsFacilityCodeClass1.Name,
                        },
                        f.CmFacility.ThirdClassId,
                        ThirdClass = new {
                            f.CmFacility.FmsFacilityCodeClass2.Name,
                        },
                    },
                }).ToList(),
                FmsWorkRequestToAccident = x.FmsWorkRequest.FmsWorkRequestToAccident.Select(f => new {
                    f.SiteId,
                    f.WorkRequestId,
                    f.AccidentId,
                    FmsAccident = new {
                        f.FmsAccident.SiteId,
                        f.FmsAccident.AccidentId,
                        f.FmsAccident.Name,
                        f.FmsAccident.AccidentTypeId,
                        AccidentTypeName = f.FmsAccident.FmsAccidentCodeType.Name,
                        Dates = new {
                            StartDate = f.FmsAccident.StartDate == null ? null : ((DateTime)f.FmsAccident.StartDate).ToString("yyyy.MM.dd"),
                            EndDate = f.FmsAccident.EndDate == null ? null : ((DateTime)f.FmsAccident.EndDate).ToString("yyyy.MM.dd"),
                        },
                        f.FmsAccident.DepartmentId,
                        DepartmentName = f.FmsAccident.CmDepartment.Name,
                        f.FmsAccident.AccidentLocation,
                    },
                }).ToList(),
                FmsWorkRequestToComplaint = x.FmsWorkRequest.FmsWorkRequestToComplaint.Select(f => new {
                    f.SiteId,
                    f.WorkRequestId,
                    f.ComplaintId,
                    FmsComplaints = new {
                        f.FmsComplaints.SiteId,
                        f.FmsComplaints.ComplaintId,
                        f.FmsComplaints.Name,
                        f.FmsComplaints.ComplaintTypeId,
                        ComplaintTypeName = f.FmsComplaints.FmsComplaintCodeType.Name,
                        Dates = new {
                            StartDate = f.FmsComplaints.StartDate == null ? null : ((DateTime)f.FmsComplaints.StartDate).ToString("yyyy.MM.dd"),
                            EndDate = f.FmsComplaints.EndDate == null ? null : ((DateTime)f.FmsComplaints.EndDate).ToString("yyyy.MM.dd"),
                        },
                        f.FmsComplaints.DepartmentId,
                        DepartmentName = f.FmsComplaints.CmDepartment.Name,
                        f.FmsComplaints.ComplaintLocation,
                    },
                }).ToList(),
            }).FirstOrDefault();
            return Ok(item);
        }

        /// <summary>
        /// 작업내 사용 자재목록 조회
        /// </summary>
        [HttpGet("[action]")]
        public IActionResult Materials([FromQuery] PagingRequest req, [FromQuery] string siteId, [FromQuery] string workRequestId) {
            var query = _context.FmsWorkResultCheckItemMaterial as IQueryable<FmsWorkResultCheckItemMaterial>;
            query = query.Filter(req.conditions);
            query = query.Sort(req.sort);
            query = query.Where(
                x => x.SiteId == Util.ToInt(siteId)
                && x.WorkRequestId == Util.ToInt(workRequestId)
            );
            var list = query.Select(x => new {
                x.FmsMaterial.Name,
                x.FmsMaterial.Standard,
                x.MaterialCount,
            });
            return Ok(list);
        }

        /// <summary>
        /// 작업이력 조회
        /// </summary>
        [HttpGet("[action]")]
        public IActionResult CheckItems([FromQuery] PagingRequest req, [FromQuery] string siteId, [FromQuery] string workRequestId) {
            var query = _context.FmsWorkResultCheckItem as IQueryable<FmsWorkResultCheckItem>;
            query = query.Filter(req.conditions);
            query = query.Sort(req.sort);
            query = query.Where(
                x => x.SiteId == Util.ToInt(siteId)
                && x.WorkRequestId == Util.ToInt(workRequestId)
            );
            var list = query.Select(x => new {
                x.SiteId,
                x.WorkRequestId,
                x.CheckItemId,
                x.CheckDate,
                x.TextResult,
                x.BoolResult,
                Title = x.CheckDate.ToString("yyyy-MM-dd") + "-" + x.TextResult,
                CmFile1 = _storage.ParseFile(x.CmFile1),
                CmFile2 = _storage.ParseFile(x.CmFile2),
            });
            return Ok(list);
        }

        /// <summary>
        /// 작업이력 항목 조회 (이력 내 사용 자재목록 포함하여 조회)
        /// </summary>
        [HttpGet("[action]")]
        public IActionResult GetCheckItem([FromQuery] string siteId, [FromQuery] string workRequestId, [FromQuery] string checkItemId) {
            var query = _context.FmsWorkResultCheckItem.AsExpandable() as IQueryable<FmsWorkResultCheckItem>;
            query = query.Where(
                x => x.SiteId == Util.ToInt(siteId)
                && x.WorkRequestId == Util.ToInt(workRequestId)
                && x.CheckItemId == Util.ToInt(checkItemId)
            );
            var item = query.Select(x => new {
                x.SiteId,
                x.WorkRequestId,
                x.CheckItemId,
                x.CheckDate,
                x.TextResult,
                x.BoolResult,
                CmFile1 = _storage.ParseFile(x.CmFile1),
                CmFile2 = _storage.ParseFile(x.CmFile2),
                WorkProgressId = x.FmsWorkResult.FmsWorkRequest.WorkProgressId,
                FmsWorkResultCheckItemMaterial = x.FmsWorkResultCheckItemMaterial.Select(f => new {
                    f.CheckItemId,
                    f.CheckItemMaterialId,
                    f.MaterialId,
                    f.MaterialCode,
                    f.MaterialCount,
                    f.Name,
                    FmsMaterial = new {
                        f.FmsMaterial.MaterialId,
                        f.FmsMaterial.MaterialCode,
                        f.FmsMaterial.Name,
                        f.FmsMaterial.Standard,
                        f.FmsMaterial.Unit,
                    },
                    StockCount = FmsMaterial.GetStockCount.Invoke(f.FmsMaterial),
                    StockAmount = FmsMaterial.GetStockAmount.Invoke(f.FmsMaterial),
                }).ToList()
            }).FirstOrDefault();
            return Ok(item);
        }


        /// <summary>
        /// 작업진행목록 / 작업완료목록 조회
        /// </summary>
        [HttpGet("[action]")]
        public IActionResult FacilityList([FromQuery] PagingRequest req) {

            var query = _FilterAndSort_2(req);
            query = query.Where(x => x.FmsWorkResult.IsConfirmed);


            var list = query.Select(x => new {
                x.SiteId,
                Site = x.FmsWorkResult.FmsWorkRequest.Site.Name,
                x.WorkRequestId,
                x.FacilityCode,
                FirstClassName = x.CmFacility.FmsFacilityCodeClass.Name,
                SecondClassName = x.CmFacility.FmsFacilityCodeClass1.Name,
                ThirdClassName = x.CmFacility.FmsFacilityCodeClass2.Name,
                FacilityName = x.CmFacility.Name,
                WorkType = x.FmsWorkResult.FmsWorkRequest.WorkType.Name,
                StartDate = x.FmsWorkResult.StartDate.ToString("yyyy-MM-dd"),
                EndDate = x.FmsWorkResult.EndDate.ToString("yyyy-MM-dd"),
                Title = x.FmsWorkResult.FmsWorkOrder.Title
            });
            var paging = PagingList.Pagination(list, req.page, req.limit);
            return Ok(paging);
        }

        /// <summary>
        /// 작업진행 저장 (작업대기 미사용시 종료일 수정)
        /// </summary>
        [HttpPost("[action]")]
        public IActionResult Save([FromBody] FmsWorkResult data) {
            _logger.LogInformation("Save");
            //_logger.LogInformation(data.Dump());

            ModelState.RemoveStartOf("FmsWorkRequest");
            ModelState.RemoveStartOf("FmsWorkOrder");
            if (ModelState.IsValid) {
                _service.Save(data);
            } else {
                return BadRequest(ModelState);
            }
            return Ok();
        }

        /// <summary>
        /// 작업이력 저장 (완료처리 및 보류처리 포함)
        /// </summary>
        [HttpPost("[action]")]
        public IActionResult SaveCheckItem([FromBody] FmsWorkResultCheckItem data) {
            _logger.LogInformation("Save");
            //_logger.LogInformation(data.Dump());

            ModelState.RemoveStartOf("CmFile1");
            ModelState.RemoveStartOf("CmFile2");
            ModelState.RemoveStartOf("FmsWorkResultCheckItemMaterial");
            if (ModelState.IsValid) {
                _service.SaveCheckItem(data, User.Identity.Name);
            } else {
                return BadRequest(ModelState);
            }
            return Ok();
        }

        /// <summary>
        /// 작업진행(보류해제)
        /// </summary>
        [HttpPost("[action]")]
        public IActionResult Continue([FromBody] FmsWorkResult data) {
            _service.Continue(data);
            return Ok();
        }

        /// <summary>
        /// 작업보류
        /// </summary>
        [HttpPost("[action]")]
        public IActionResult Hold([FromBody] FmsWorkResult data) {
            _service.Hold(data.FmsWorkRequest);
            return Ok();
        }

        /// <summary>
        /// 작업완료
        /// </summary>
        [HttpPost("[action]")]
        public IActionResult Complete([FromBody] FmsWorkResult data) {
            _service.CompleteWithAdditionalData(data);
            return Ok();
        }

        /// <summary>
        /// 승인
        /// </summary>
        [HttpPost("[action]")]
        public IActionResult Confirm([FromBody] FmsWorkResult data, [FromQuery] DateTime? date) {
            _service.Confirm(data, date);
            return Ok();
        }

        /// <summary>
        /// 차기작업 확정일자 및 현작업 종료일자 조회
        /// { WorkDueDate, EndDate }
        /// </summary>
        [HttpGet("[action]")]
        public IActionResult GetAvailDueDate([FromQuery] string siteId, [FromQuery] string workRequestId) {
            return Ok(_service.GetAvailDueDate(Util.ToInt(siteId), Util.ToInt(workRequestId)));
        }

        [HttpDelete("{siteId}/{workRequestId}")]
        public IActionResult Delete(int siteId, int workRequestId) {
            _service.Delete(siteId, workRequestId);
            // _scheduleService.DeleteWithResult(siteId, workRequestId);
            return Ok();
        }

        // 검색 & 정렬 공통
        private IQueryable<FmsWorkResult> _FilterAndSort(PagingRequest req) {
            var query = _service.GetAll();

            // 기본 Entity 검색
            query = query.Filter(req.conditions);

            if (req.siteId != null)
                query = query.Where(x => x.SiteId == req.siteId);

            if (req.siteIds != null && req.siteIds.Length > 0) {
                query = query.Where(x => req.siteIds.Contains(x.SiteId));
            }

            if (req.businessFieldId != null) {
                query = query.Where(x => x.SiteId == req.siteId);
                query = query.Where(x => x.FmsWorkRequest.BusinessFieldId == req.businessFieldId || x.FmsWorkRequest.CmBusinessField.Name == "공통");
            }

            if (req.conditions != null) {
                foreach (var item in req.conditions) {
                    if (item.field == "FacilityTypeId") {
                        query = query.Where(x => x.FmsWorkResultToFacility.Any(f => f.CmFacility.FacilityTypeId == Util.ToInt(item.value)));
                    }
                }
            }

            // 기본 Entity 정렬
            //query = query.Sort(req.sort);

            if (req.sort != null) {
                if (req.sort.field == "Custom") {
                    query = query.OrderByDescending(x => x.StartDate).ThenBy(x => x.FmsWorkRequest.Title).ThenBy(x => x.FmsWorkRequest.Site.SortOrderNo);
                } else if (req.sort.field == "Def") {
                    query = query.OrderBy(x => x.FmsWorkRequest.Site.SortOrderNo);
                } else {
                    query = query.Sort(req.sort);
                }
            }


            return query;
        }
        private IQueryable<FmsWorkResultToFacility> _FilterAndSort_2(PagingRequest req) {
            var query = _service_2.GetAll();

            // 기본 Entity 검색
            query = query.Filter(req.conditions);

            if (req.siteId != null) {
                query = query.Where(x => x.SiteId == Util.ToInt(req.siteId));
            }

            if (req.businessFieldId != null) {
                query = query.Where(x => x.SiteId == req.siteId);
                query = query.Where(x => x.FmsWorkResult.FmsWorkRequest.BusinessFieldId == req.businessFieldId || x.FmsWorkResult.FmsWorkRequest.CmBusinessField.Name == "공통");
            }


            // 기본 Entity 정렬
            query = query.Sort(req.sort);

            return query;
        }


        //작업승인 달력 상세(리스트)
        [HttpGet("[action]")]
        public IActionResult CustomList([FromQuery] PagingRequest req, DateTime dates) {

            DateTime selectMonth;
            selectMonth = new DateTime(dates.Year, dates.Month, dates.Day);
            var startDate = selectMonth;
            var endDate = selectMonth.AddDays(1).AddSeconds(-1);

            var list = _service.GetAll()
          .Where(x => x.FmsWorkRequest.StartWorkDate >= startDate && x.FmsWorkRequest.StartWorkDate <= endDate && x.FmsWorkRequest.WorkProgressId == 6)
          .Select(x => new { Title = "[" + x.FmsWorkRequest.Site.Name + "]" + x.FmsWorkRequest.Title, x.SiteId, x.WorkRequestId, WorkTypeId = x.FmsWorkRequest.WorkTypeId });




            var paging = PagingList.Pagination(list, req.page, req.limit);
            return Ok(paging);
        }



        //작업승인 달력 상세(리스트)
        [HttpGet("[action]")]
        public IActionResult CustomListSite([FromQuery] PagingRequest req, int siteId, DateTime dates) {

            DateTime selectMonth;
            selectMonth = new DateTime(dates.Year, dates.Month, dates.Day);
            var startDate = selectMonth;
            var endDate = selectMonth.AddDays(1).AddSeconds(-1);

            var list = _service.GetAll()
          .Where(x => x.SiteId == siteId && x.FmsWorkRequest.StartWorkDate >= startDate && x.FmsWorkRequest.StartWorkDate <= endDate && x.FmsWorkRequest.WorkProgressId == 6)
          .Select(x => new { x.FmsWorkRequest.Title, x.SiteId, x.WorkRequestId, WorkTypeId = x.FmsWorkRequest.WorkTypeId });




            var paging = PagingList.Pagination(list, req.page, req.limit);
            return Ok(paging);
        }



        //본사용 작업승인 달력
        [HttpGet("[action]")]
        public IActionResult WorkStateCalendar(int? year, int? month) {
            //var siteId = User.GetSiteId();


            DateTime selectMonth;
            if (year == null || month == null) {
                selectMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            } else {
                selectMonth = new DateTime(year.Value, month.Value, 1);
            }
            var startDate = selectMonth.AddDays(-7);
            var endDate = selectMonth.AddDays(37);


            //주별중점업무
            var WeekQuery = _weekWorkService.GetWeek(100, startDate, endDate);
            var weekList = WeekQuery.Select(x => new {
                Title = x.WorkName,
                Start = x.WorkDate.ToString("yyyy-MM-dd"),
                End = x.WorkDate.AddDays(7).ToString("yyyy-MM-dd"),
                Id = x.WeekKeyWorkId,
                GroupId = 0,
                Type = "주별",
            }).ToList();

            //     // 계획
            //     var requestQuery = _requestService.GetAll()
            //                  .Where(x => x.StartWorkDate.Date >= startDate.Date && x.StartWorkDate.Date <= endDate.Date)
            //                  .AsEnumerable()
            //                  .Select(x => new { WorkDate = x.StartWorkDate.ToString("yyyy-MM-dd") }).ToList();

            //     var requestGroupQuery = from x in requestQuery
            //                             group x by x.WorkDate into g
            //                             select new {
            //                                 WorkDate = g.Key,
            //                                 Count = g.Count(),
            //                             };

            //     var requestList = requestGroupQuery.Select(x => new {
            //         Title = "계획 : " + x.Count.ToString("#,###") + " 건",
            //         Start = x.WorkDate,
            //         End = x.WorkDate,
            //         Id = x.WorkDate + "|1",
            //         GroupId = 1,
            //         Type = "예정",

            //     });

            //     // 승인
            //     var resultQuery = _service.GetAll()
            //    .Where(x => x.FmsWorkRequest.StartWorkDate.Date >= startDate.Date && x.FmsWorkRequest.StartWorkDate.Date <= endDate.Date && x.FmsWorkRequest.WorkProgressId == 6)
            //    .AsEnumerable()
            //    .Select(x => new { StartWorkDate = x.ConfirmedDate != null ? Convert.ToDateTime(x.FmsWorkRequest.StartWorkDate.Date).ToString("yyyy-MM-dd") : "" }).ToList();

            //     var resultGroupQuery = from x in resultQuery
            //                            group x by x.StartWorkDate into g
            //                            select new {
            //                                StartWorkDate = g.Key,
            //                                Count = g.Count(),

            //                            };

            //     // 승인을 완료로 문구만 변경 (2020.07.29)
            //     var resultList = resultGroupQuery.Select(x => new CalendarEvent {
            //         Title = "완료 : " + x.Count.ToString("#,###") + " 건",
            //         Start = x.StartWorkDate,
            //         End = x.StartWorkDate,
            //         Id = x.StartWorkDate + "|6",
            //         GroupId = 2,
            //         Type = "승인",
            //     });

            // 계획/승인 - 통합 (2020.07.29)
            var reqsList = _service.GetRequestResult(null, startDate, endDate);


            var siteId = 100;
            // 휴일
            var holidayList = _GetHolidayList(siteId, selectMonth.Year, selectMonth.Month, startDate, endDate);

            // 주말
            var weekend = _context.CmHolidayWeekend.Where(
                x => x.SiteId == siteId
                && x.IsUse == true
            ).FirstOrDefault();

            // 집중업무
            var workName = _monthWorkService.GetKeyWork(siteId, selectMonth.Month);

            if (weekend != null) {
            }

            var result = new {
                Year = selectMonth.Year,
                Month = selectMonth.Month,
                Theme = workName,
                StartDate = startDate.ToString("yyyy-MM-dd"),
                EndDate = endDate.ToString("yyyy-MM-dd"),
                // RequestList = requestList,
                // ResultList = resultList,
                HolidayList = holidayList,
                WeekList = weekList,
                Saturday = weekend?.Saturday ?? false,
                Sunday = weekend?.Sunday ?? false,
                RequestResultList = reqsList,
            };

            return Ok(result);
        }


        //현장용 작업승인 달력
        [HttpGet("[action]")]
        public IActionResult WorkStateCalendarSite(int siteId, int? year, int? month) {
            //var siteId = User.GetSiteId();


            DateTime selectMonth;
            if (year == null || month == null) {
                selectMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            } else {
                selectMonth = new DateTime(year.Value, month.Value, 1);
            }
            var startDate = selectMonth.AddDays(-7);
            var endDate = selectMonth.AddDays(37);


            //주별중점업무
            var WeekQuery = _weekWorkService.GetWeek(siteId, startDate, endDate);
            var weekList = WeekQuery.Select(x => new {
                Title = x.WorkName,
                Start = x.WorkDate.ToString("yyyy-MM-dd"),
                End = x.WorkDate.AddDays(1).ToString("yyyy-MM-dd"),
                Id = x.WeekKeyWorkId,
                GroupId = 0,
                Type = "주별",
            }).ToList();

            // // 계획
            // var requestQuery = _requestService.GetAll()
            //              .Where(x => x.SiteId == siteId && x.StartWorkDate.Date >= startDate.Date && x.StartWorkDate.Date <= endDate.Date)
            //              .AsEnumerable()
            //              .Select(x => new { WorkDate = x.StartWorkDate.ToString("yyyy-MM-dd") }).ToList();

            // var requestGroupQuery = from x in requestQuery
            //                         group x by x.WorkDate into g
            //                         select new {
            //                             WorkDate = g.Key,
            //                             Count = g.Count(),
            //                         };

            // var requestList = requestGroupQuery.Select(x => new {
            //     Title = "계획 : " + x.Count.ToString("#,###") + " 건",
            //     Start = x.WorkDate,
            //     End = x.WorkDate,
            //     Id = x.WorkDate + "|1",
            //     GroupId = 1,
            //     Type = "예정",
            // });

            // // 승인
            // var resultQuery = _service.GetAll()
            //             .Where(x => x.SiteId == siteId && x.FmsWorkRequest.StartWorkDate.Date >= startDate.Date && x.FmsWorkRequest.StartWorkDate.Date <= endDate.Date && x.FmsWorkRequest.WorkProgressId == 6)
            //             .AsEnumerable()
            //             .Select(x => new { StartWorkDate = x.ConfirmedDate != null ? Convert.ToDateTime(x.FmsWorkRequest.StartWorkDate.Date).ToString("yyyy-MM-dd") : "" }).ToList();

            // var resultGroupQuery = from x in resultQuery
            //                        group x by x.StartWorkDate into g
            //                        select new {
            //                            StartWorkDate = g.Key,
            //                            Count = g.Count(),
            //                        };

            // // 승인을 완료로 문구만 변경 (2020.07.29)
            // var resultList = resultGroupQuery.Select(x => new CalendarEvent {
            //     Title = "완료 : " + x.Count.ToString("#,###") + " 건",
            //     Start = x.StartWorkDate,
            //     End = x.StartWorkDate,
            //     Id = x.StartWorkDate + "|6",
            //     GroupId = 2,
            //     Type = "승인",
            // });

            // 계획/승인 - 통합 (2020.07.29)
            var reqsList = _service.GetRequestResult(siteId, startDate, endDate);

            // 휴일
            var holidayList = _GetHolidayList(siteId, selectMonth.Year, selectMonth.Month, startDate, endDate);

            // 주말
            var weekend = _context.CmHolidayWeekend.Where(
                x => x.SiteId == siteId
                && x.IsUse == true
            ).FirstOrDefault();

            // 집중업무
            var workName = _monthWorkService.GetKeyWork(siteId, selectMonth.Month);

            if (weekend != null) {
            }

            var result = new {
                Year = selectMonth.Year,
                Month = selectMonth.Month,
                Theme = workName,
                StartDate = startDate.ToString("yyyy-MM-dd"),
                EndDate = endDate.ToString("yyyy-MM-dd"),
                // RequestList = requestList,
                // ResultList = resultList,
                HolidayList = holidayList,
                WeekList = weekList,
                Saturday = weekend?.Saturday ?? false,
                Sunday = weekend?.Sunday ?? false,
                RequestResultList = reqsList,
            };

            return Ok(result);
        }


        //본사용 작업계획 (달력)
        private IQueryable<CalendarEvent> _GetRequestEventList(DateTime startDate, DateTime endDate) {




            // var query = from x in _context.FmsWorkRequest
            //             where x.FmsWorkResult == null
            //             where x.StartWorkDate.Date >= startDate.Date && x.StartWorkDate.Date <= endDate.Date
            //             && x.WorkProgressId == 1 // 작업계획
            //             && (x.FmsWorkSchedule == null || (x.FmsWorkSchedule != null && x.FmsWorkSchedule.IsUse == true))
            //             select new { x.StartWorkDate };


            // var query = from x in _context.FmsWorkSchedule
            //             where x.WorkDueDate.Date >= startDate.Date && x.WorkDueDate.Date <= endDate.Date

            //             select new {
            //                 x.WorkDueDate
            //             };



            var query = _requestService.GetAll()
            .Where(x => x.FmsWorkResult == null)
            .Where(x => x.StartWorkDate.Date >= startDate.Date && x.StartWorkDate.Date <= endDate.Date && x.WorkProgressId == 1)
            .Where(x => (x.FmsWorkSchedule == null || (x.FmsWorkSchedule != null && x.FmsWorkSchedule.IsUse == true)))
            //query.Where(x=>x.FmsWorkResult == null );
            //.AsEnumerable()
            .Select(x => new { WorkDate = x.StartWorkDate.ToString("yyyy-MM-dd") });



            var groupQuery = from x in query
                             group x by x.WorkDate into g
                             select new {
                                 WorkDate = g.Key,
                                 Count = g.Count(),
                             };

            var list = groupQuery.Select(x => new CalendarEvent {
                Title = "계획 : " + x.Count.ToString(),
                Start = x.WorkDate,
                End = x.WorkDate,
                Id = x.WorkDate + "|1",
                GroupId = 1,
                Type = "예정",

            });


            return list;
        }
        //본사용 작업승인 (달력)
        private IQueryable<CalendarEvent> _GetResultEventList(DateTime startDate, DateTime endDate) {



            // var query = from x in _context.FmsWorkResult
            //             where x.ConfirmedDate >= startDate.Date && x.ConfirmedDate <= endDate.Date
            //             where x.FmsWorkRequest.WorkProgressId == 6
            //             select new { x.ConfirmedDate };


            var query = _service.GetAll()
            .Where(x => x.ConfirmedDate >= startDate.Date && x.ConfirmedDate <= endDate.Date && x.FmsWorkRequest.WorkProgressId == 6)
            .Select(x => new { ConfirmedDate = x.ConfirmedDate != null ? Convert.ToDateTime(x.ConfirmedDate).ToString("yyyy-MM-dd") : "" });




            var groupQuery = from x in query
                             group x by x.ConfirmedDate into g
                             select new {
                                 ConfirmedDate = g.Key,
                                 Count = g.Count(),

                             };

            var list = groupQuery.Select(x => new CalendarEvent {
                Title = "승인 : " + x.Count.ToString(),
                Start = x.ConfirmedDate,
                End = x.ConfirmedDate,
                //WorkType = x.FmsWorkRequest.WorkType.Name,
                Id = x.ConfirmedDate + "|6",
                GroupId = 2,
                Type = "승인",
                //WorkRequestId = x.WorkRequestId,
            });

            return list;
        }






        //현장용 작업승인 달력
        [HttpGet("[action]")]
        public IActionResult WorkCalendar(int siteId, string workProgressId, int? year, int? month) {
            //var siteId = User.GetSiteId();


            DateTime selectMonth;
            if (year == null || month == null) {
                selectMonth = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            } else {
                selectMonth = new DateTime(year.Value, month.Value, 1);
            }
            var startDate = selectMonth.AddDays(-7);
            var endDate = selectMonth.AddDays(37);

            // // 작업예정
            // var requestList = _GetRequestEventList(siteId, startDate, endDate);

            // 작업진행 및 승인
            var resultList = _GetResultEventList(siteId, workProgressId, startDate, endDate);


            if (siteId == 0) siteId = 100;
            // 휴일
            var holidayList = _GetHolidayList(siteId, selectMonth.Year, selectMonth.Month, startDate, endDate);

            // 주말
            var weekend = _context.CmHolidayWeekend.Where(
                x => x.SiteId == siteId
                && x.IsUse == true
            ).FirstOrDefault();

            // 집중업무
            var workName = _monthWorkService.GetKeyWork(siteId, selectMonth.Month);

            //주별중점업무
            var WeekQuery = _weekWorkService.GetWeek(siteId, startDate, endDate);
            var weekList = WeekQuery.Select(x => new {
                Title = x.WorkName,
                Start = x.WorkDate.ToString("yyyy-MM-dd"),
                End = x.WorkDate.AddDays(7).ToString("yyyy-MM-dd"),
                Id = x.WeekKeyWorkId,
                //SiteId = x.SiteId,
                GroupId = 0,
                //Date = x.WorkDate.ToString("yyyy-MM-dd"),
                Type = "주별",
            }).ToList();

            if (weekend != null) {
            }

            var result = new {
                Year = selectMonth.Year,
                Month = selectMonth.Month,
                Theme = workName,
                StartDate = startDate.ToString("yyyy-MM-dd"),
                EndDate = endDate.ToString("yyyy-MM-dd"),
                //RequestList = requestList,
                ResultList = resultList,
                HolidayList = holidayList,
                Saturday = weekend?.Saturday ?? false,
                Sunday = weekend?.Sunday ?? false,
                WeekList = weekList,
            };

            return Ok(result);
        }

        //현장용 작업계획 (달력)
        private IQueryable<CalendarEvent> _GetRequestEventList(int? siteId, DateTime startDate, DateTime endDate) {
            var events = _context.FmsWorkRequest.Select(x => x);
            if (siteId != null) {
                events = events.Where(x => x.SiteId == siteId.Value);
            }

            var query = from x in events
                        where x.FmsWorkResult == null
                        where x.StartWorkDate.Date >= startDate.Date && x.StartWorkDate.Date <= endDate.Date
                        && x.WorkProgressId == 1 // 작업계획
                        && (x.FmsWorkSchedule == null || (x.FmsWorkSchedule != null && x.FmsWorkSchedule.IsUse == true))
                        select x;

            var list = query.Select(x => new CalendarEvent {
                Title = x.Title,
                Start = x.StartWorkDate.ToString("yyyy-MM-dd"),
                End = x.StartWorkDate.ToString("yyyy-MM-dd"),
                WorkType = x.WorkType.Name,
                Id = x.SiteId.ToString() + "-" + x.WorkRequestId.ToString(),
                GroupId = x.WorkTypeId,
                Type = "예정",
                WorkRequestId = x.WorkRequestId,
            });

            return list;
        }



        //현장용 작업단계별 (달력)
        private IQueryable<CalendarEvent> _GetResultEventList(int? siteId, string workProgressId, DateTime startDate, DateTime endDate) {

            int nWorkProgressId = 0;
            int.TryParse(workProgressId, out nWorkProgressId);
            var events = _context.FmsWorkResult.Select(x => x);
            if (siteId != null && siteId != 0) {
                events = events.Where(x => x.SiteId == siteId.Value);
            }

            if (nWorkProgressId == 4) {
                // 작업진행 목록에서는 작업진행(4), 작업보류(7) 데이터를 조회
                events = events.Where(x => (x.FmsWorkRequest.WorkProgressId == 4 || x.FmsWorkRequest.WorkProgressId == 7));
            }
            if (nWorkProgressId == 6) {
                // 작업완료 목록에서는 작업완료(5) 데이터를 조회
                events = events.Where(x => x.FmsWorkRequest.WorkProgressId == 6);
            }


            var query = from x in events
                        where x.StartDate.Date >= startDate.Date && x.StartDate <= endDate.Date
                        select x;

            var list = query.Select(x => new CalendarEvent {
                Title = siteId == 0 ? "[" + x.FmsWorkRequest.Site.Name + "]" + x.FmsWorkRequest.Title : x.FmsWorkRequest.Title,
                Start = x.StartDate.ToString("yyyy-MM-dd"),
                End = x.EndDate.ToString("yyyy-MM-dd"),
                WorkType = x.FmsWorkRequest.WorkType.Name,
                Id = x.SiteId.ToString() + "-" + x.WorkRequestId.ToString(),
                GroupId = x.FmsWorkRequest.WorkTypeId,
                Type = "진행",
                WorkRequestId = x.WorkRequestId,
            });

            return list;
        }

        private IList<CalendarBackground> _GetHolidayList(int siteId, int year, int month, DateTime startDate, DateTime endDate) {
            var list = new List<CalendarBackground>();

            var holidays = _context.CmHoliday.Where(
                x => x.SiteId == siteId
                && x.IsUse == true
            );

            foreach (var item in holidays) {
                if (item.IsLunar) {
                    var solar = LunarSolarConverter.LunarToSolar(new Lunar() {
                        lunarYear = year,
                        lunarMonth = item.HolidayMonth,
                        lunarDay = item.HolidayDay
                    });
                    list.Add(new CalendarBackground {
                        Title = item.Name + "(음력)",
                        Date = new DateTime(solar.solarYear, solar.solarMonth, solar.solarDay).ToString("yyyy-MM-dd"),
                        Type = "공휴일",
                    });
                } else {
                    list.Add(new CalendarBackground {
                        Title = item.Name,
                        Date = new DateTime(year, item.HolidayMonth, item.HolidayDay).ToString("yyyy-MM-dd"),
                        Type = "공휴일",
                    });
                }
            }

            var query = from x in _context.CmHolidayCustom
                        where x.SiteId == siteId
                        where x.HolidayDate.Date >= startDate.Date && x.HolidayDate >= endDate.Date
                        select x;

            var customs = query.Select(x => new CalendarBackground {
                Title = x.Name,
                Date = x.HolidayDate.ToString("yyyy-MM-dd"),
                Type = "휴일",
            });

            return list;
        }


        /** 
         * 작업 현황(상태별)
         */
        [HttpGet("[action]")]
        public IActionResult WorkStateSummary(int? siteId) {
            if (siteId == null) siteId = User.GetSiteId();

            var today = DateTime.Now.Date;
            var startDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var endDate = startDate.AddMonths(1).AddDays(-1);



            //작업 대기
            var wating = (from x in _context.FmsWorkRequest
                          where x.SiteId == siteId
                          where x.StartWorkDate.Date >= startDate && x.StartWorkDate.Date <= endDate
                          where new int[] { 3 }.Contains(x.WorkProgress.WorkProgressId) // 3:대기
                          select x).Count();

            // 작업 진행
            var working = (from x in _context.FmsWorkResult
                           where x.SiteId == siteId
                           //where x.StartDate.Date >= startDate && x.StartDate.Date <= endDate
                           where x.EndDate.Date >= startDate && x.StartDate.Date <= endDate
                           where new int[] { 4 }.Contains(x.FmsWorkRequest.WorkProgress.WorkProgressId) // 4:진행
                           select x).Count();
            // 작업 보류
            var holding = (from x in _context.FmsWorkResult
                           where x.SiteId == siteId
                           where x.StartDate.Date >= startDate && x.StartDate.Date <= endDate
                           where new int[] { 7 }.Contains(x.FmsWorkRequest.WorkProgress.WorkProgressId) // 7:보류
                           select x).Count();

            // 작업 완료
            var completed = (from x in _context.FmsWorkResult
                             where x.SiteId == siteId
                             where x.EndDate.Date >= startDate && x.StartDate.Date <= endDate
                             where new int[] { 5 }.Contains(x.FmsWorkRequest.WorkProgress.WorkProgressId) // 5:완료
                             select x).Count();

            // 작업 승인
            var approvaled = (from x in _context.FmsWorkResult
                              where x.SiteId == siteId
                              where x.EndDate.Date >= startDate && x.StartDate.Date <= endDate
                              where new int[] { 6 }.Contains(x.FmsWorkRequest.WorkProgress.WorkProgressId) // 6:승인
                              select x).Count();

            // 미결 일별보고서
            var unapprovalReport = (from x in _context.FmsDailyReport
                                    where x.SiteId == siteId
                                    where x.AddDate.Date == today
                                    where x.ApproverUserId == null
                                    select x).Count();

            return Ok(new {
                work = new {
                    작업대기 = wating,
                    작업진행 = working,
                    작업완료 = completed,
                    작업승인 = approvaled,
                    작업보류 = holding,
                },
                report = new {
                    미결일지 = unapprovalReport
                }
            });
        }

        /** 
         * (시설관리>업무분야별 작업현황)
         */
        [HttpGet("[action]")]
        public IActionResult BusinessWorkSummary(int? siteId) {
            if (siteId == null) siteId = User.GetSiteId();

            var startDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            var endDate = startDate.AddMonths(1).AddDays(-1);

            var query = from x in _context.FmsWorkResult
                        where x.SiteId == siteId
                        where x.EndDate.Date >= startDate && x.EndDate.Date <= endDate
                        select new {
                            x.FmsWorkRequest,
                            x.FmsWorkRequest.WorkProgress,
                            x.FmsWorkRequest.CmBusinessField,
                        };

            var groupQuery = from x in query
                             group x by new { x.FmsWorkRequest.WorkProgressId, x.FmsWorkRequest.BusinessFieldId } into g
                             select new {
                                 BusinessFieldId = g.Key.BusinessFieldId,
                                 BusinessFieldName = g.Min(x => x.CmBusinessField.Name),
                                 WorkProgressId = g.Key.WorkProgressId,
                                 WorkProgressName = g.Min(x => x.WorkProgress.Name),
                                 Count = g.Count(),
                             };

            var groupBusiness = from x in groupQuery
                                group x by x.BusinessFieldId into g
                                select new {
                                    BusinessFieldId = g.Key,
                                    BusinessFieldName = g.Min(x => x.BusinessFieldName),
                                    작업대기 = g.Sum(x => x.WorkProgressId == 3 ? x.Count : 0),
                                    작업진행 = g.Sum(x => x.WorkProgressId == 4 ? x.Count : 0),
                                    작업완료 = g.Sum(x => x.WorkProgressId == 5 ? x.Count : 0),
                                    작업승인 = g.Sum(x => x.WorkProgressId == 6 ? x.Count : 0),
                                    작업보류 = g.Sum(x => x.WorkProgressId == 7 ? x.Count : 0),
                                };

            return Ok(new {
                year = startDate.Year,
                month = startDate.Month,
                list = groupBusiness
            });
        }


        /** 
                * 월별 작업 현황 (관리자)
                */
        [HttpGet("[action]")]
        public IActionResult MonthlyWorkSummary(int? siteId, int? year, int? month) {
            if (siteId == null) siteId = User.GetSiteId();
            DateTime startDate;
            if (year == null || month == null) {
                startDate = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
            } else {
                startDate = new DateTime(year.Value, month.Value, 1);
            }
            var endDate = startDate.AddMonths(1).AddDays(-1);

            var query = from x in _context.FmsWorkRequest
                        where x.StartWorkDate >= startDate && x.StartWorkDate <= endDate && x.SiteId == siteId
                        where new int[] { 1 }.Contains(x.WorkProgress.WorkProgressId)
                        select new {
                            x.Site,
                            x.WorkType,
                            x.CmBusinessField,
                        };

            var groupQuery = from x in query
                             group x by new { x.WorkType.WorkTypeId, x.Site.SiteId } into g
                             select new {
                                 SiteId = g.Key.SiteId,
                                 SiteName = g.Min(x => x.Site.Name),
                                 WorkTypeId = g.Key.WorkTypeId,
                                 WorkTypeName = g.Min(x => x.WorkType.Name),
                                 Count = g.Count(),
                             };

            var groupBusiness = from x in groupQuery
                                group x by x.SiteId into g
                                select new {
                                    SiteId = g.Key,
                                    SiteName = g.Min(x => x.SiteName),
                                    정기점검 = g.Sum(x => x.WorkTypeId == 1 ? x.Count : 0),
                                    법정검사 = g.Sum(x => x.WorkTypeId == 2 ? x.Count : 0),
                                    수시점검 = g.Sum(x => x.WorkTypeId == 5 ? x.Count : 0),
                                    공사작업 = g.Sum(x => x.WorkTypeId == 6 ? x.Count : 0),
                                    법정교육 = g.Sum(x => x.WorkTypeId == 7 ? x.Count : 0),
                                };

            return Ok(new {
                // year = startDate.Year,
                // month = startDate.Month,
                work = new {
                    정기점검 = groupBusiness.Select(x => x.정기점검).FirstOrDefault(),
                    법정검사 = groupBusiness.Select(x => x.법정검사).FirstOrDefault(),
                    수시점검 = groupBusiness.Select(x => x.수시점검).FirstOrDefault(),
                    공사작업 = groupBusiness.Select(x => x.공사작업).FirstOrDefault(),
                    법정교육 = groupBusiness.Select(x => x.법정교육).FirstOrDefault(),
                }

            });
        }


        // 작업 계획/승인 달력 상세(리스트)
        [HttpGet("[action]")]
        public IActionResult CustomAllList([FromQuery] PagingRequest req, DateTime dates) {
            DateTime selectMonth;
            selectMonth = new DateTime(dates.Year, dates.Month, dates.Day);
            var startDate = selectMonth;
            var endDate = selectMonth.AddDays(1).AddSeconds(-1);

            var query = _service.GetCustomRequestResultList(null, startDate, endDate);

            var list = query.OrderBy(x => x.Site.SortOrderNo).Select(x => new {
                Title = "[" + x.Site.Name + "] " + x.Title,
                x.SiteId,
                x.WorkRequestId,
                x.WorkTypeId,
                x.WorkScheduleId,
                x.WorkProgressId,
                IsConfirmName = x.WorkProgressId == 6 ? "완료" : "",
            });

            var paging = PagingList.Pagination(list, req.page, req.limit);
            return Ok(paging);
        }

        // 작업 계획/승인 달력 상세(리스트)
        [HttpGet("[action]")]
        public IActionResult CustomAllListSite([FromQuery] PagingRequest req, int siteId, DateTime dates) {
            DateTime selectMonth;
            selectMonth = new DateTime(dates.Year, dates.Month, dates.Day);
            var startDate = selectMonth;
            var endDate = selectMonth.AddDays(1).AddSeconds(-1);

            var query = _service.GetCustomRequestResultList(siteId, startDate, endDate);

            var list = query.Select(x => new {
                x.Title,
                x.SiteId,
                x.WorkRequestId,
                x.WorkTypeId,
                x.WorkScheduleId,
                x.WorkProgressId,
                IsConfirmName = x.WorkProgressId == 6 ? "완료" : "",
            });

            var paging = PagingList.Pagination(list, req.page, req.limit);
            return Ok(paging);
        }
    }
}