public async Task <IActionResult> Post([FromBody] SubPaymentMaster nSubPaymentMaster)
        {
            if (nSubPaymentMaster != null && nSubPaymentMaster.SubPaymentDetails != null)
            {
                nSubPaymentMaster = this.helpers.AddHourMethod(nSubPaymentMaster);
                nSubPaymentMaster.SubPaymentNo = await this.GeneratedCode(nSubPaymentMaster.ProjectCodeMasterId.Value,
                                                                          nSubPaymentMaster.PaintTeamId.Value);

                nSubPaymentMaster.CreateDate = DateTime.Now;
                nSubPaymentMaster.Creator    = nSubPaymentMaster.Creator ?? "Someone";
                // Sub payment detail
                foreach (var nSubPaymentDetail in nSubPaymentMaster.SubPaymentDetails)
                {
                    if (nSubPaymentDetail == null)
                    {
                        continue;
                    }

                    nSubPaymentDetail.CreateDate = DateTime.Now;
                    nSubPaymentDetail.Creator    = nSubPaymentMaster.Creator ?? "Someone";
                    //Date change timezone
                    if (nSubPaymentDetail.PaymentDate.HasValue)
                    {
                        nSubPaymentDetail.PaymentDate = this.ChangeTimeZone(nSubPaymentDetail.PaymentDate.Value);
                    }
                    else
                    {
                        nSubPaymentDetail.PaymentDate = DateTime.Now;
                    }
                    //Relation
                }

                return(new JsonResult(await this.repository.AddAsync(nSubPaymentMaster), this.DefaultJsonSettings));
            }
            return(NotFound(new { Error = "Not found sub payment master data !!!" }));
        }
        public async Task <IActionResult> PutByNumber(int key, [FromBody] SubPaymentMaster uSubPaymentMaster)
        {
            var Message = "Sub payment master not been found.";

            if (uSubPaymentMaster != null && uSubPaymentMaster.SubPaymentDetails != null)
            {
                uSubPaymentMaster = this.helpers.AddHourMethod(uSubPaymentMaster);
                // set modified
                uSubPaymentMaster.ModifyDate = DateTime.Now;
                uSubPaymentMaster.Modifyer   = uSubPaymentMaster.Modifyer ?? "Someone";

                foreach (var uSubPaymentDetail in uSubPaymentMaster.SubPaymentDetails)
                {
                    if (uSubPaymentDetail == null)
                    {
                        continue;
                    }

                    if (uSubPaymentDetail.SubPaymentDetailId > 0)
                    {
                        uSubPaymentDetail.ModifyDate  = uSubPaymentMaster.ModifyDate;
                        uSubPaymentDetail.Modifyer    = uSubPaymentMaster.Modifyer;
                        uSubPaymentDetail.PaymentDate = this.ChangeTimeZone(uSubPaymentDetail.PaymentDate.Value);
                    }
                    else
                    {
                        uSubPaymentDetail.CreateDate = uSubPaymentMaster.ModifyDate;
                        uSubPaymentDetail.Creator    = uSubPaymentMaster.Modifyer;
                        if (uSubPaymentDetail.PaymentDate.HasValue)
                        {
                            uSubPaymentDetail.PaymentDate = this.ChangeTimeZone(uSubPaymentDetail.PaymentDate.Value);
                        }
                        else
                        {
                            uSubPaymentDetail.PaymentDate = DateTime.Now;
                        }
                    }
                }

                // update Master not update Detail it need to update Detail directly
                var updateComplate = await this.repository.UpdateAsync(uSubPaymentMaster, key);

                if (updateComplate != null)
                {
                    // filter
                    Expression <Func <SubPaymentDetail, bool> > conditionSubDetail = m => m.SubPaymentMasterId == key;
                    var dbSubDetails = this.repositorySubPaymentDetail.FindAll(conditionSubDetail);

                    //Remove SubPaymentDetail if edit remove it
                    foreach (var dbSubDetail in dbSubDetails)
                    {
                        if (!uSubPaymentMaster.SubPaymentDetails.Any(x => x.SubPaymentDetailId == dbSubDetail.SubPaymentDetailId))
                        {
                            await this.repositorySubPaymentDetail.DeleteAsync(dbSubDetail.SubPaymentDetailId);
                        }
                    }

                    //Update SubPaymentDetail or New SubPaymentDetail
                    foreach (var uSubPaymentDetail in uSubPaymentMaster.SubPaymentDetails)
                    {
                        if (uSubPaymentDetail == null)
                        {
                            continue;
                        }

                        if (uSubPaymentDetail.SubPaymentDetailId > 0)
                        {
                            await this.repositorySubPaymentDetail.UpdateAsync(uSubPaymentDetail, uSubPaymentDetail.SubPaymentDetailId);
                        }
                        else
                        {
                            if (uSubPaymentDetail.SubPaymentMasterId is null || uSubPaymentDetail.SubPaymentMasterId < 1)
                            {
                                uSubPaymentDetail.SubPaymentMasterId = uSubPaymentMaster.SubPaymentMasterId;
                            }

                            await this.repositorySubPaymentDetail.AddAsync(uSubPaymentDetail);
                        }
                    }
                }

                return(new JsonResult(updateComplate, this.DefaultJsonSettings));
            }

            return(NotFound(new { Error = Message }));
        }
        public async Task <IActionResult> CalclateSubPaymentMaster([FromBody] SubPaymentMaster CurrentSubPayment)
        {
            var message = "Not beed found data.";

            try
            {
                if (CurrentSubPayment != null)
                {
                    if (CurrentSubPayment.ProjectCodeMasterId > 0 && CurrentSubPayment.PaintTeamId > 0)
                    {
                        #region PaintProgress
                        // get WorkLoad for paint team and project
                        var QueryPaintData = this.repositoryPaintTaskDetail.GetAllAsQueryable()
                                             .Where(x => x.PaintTeamId == CurrentSubPayment.PaintTeamId &&
                                                    x.PaintTaskMaster.RequirePaintingList
                                                    .RequirePaintingMaster.ProjectCodeSub
                                                    .ProjectCodeMasterId == CurrentSubPayment.ProjectCodeMasterId &&
                                                    x.PaintTaskMaster.PaintTaskStatus != PaintTaskStatus.Cancel &&
                                                    x.PaymentDetailId != null &&
                                                    x.PaintWorkItemId != null)
                                             .Include(x => x.PaintTaskMaster)
                                             .Include(x => x.PaintWorkItem)
                                             .Include(x => x.PaymentDetail.PaymentCostHistorys);

                        var DataPaint = await QueryPaintData.Select(x => new CalclateProgressViewModel
                        {
                            PaymentDetailId      = x.PaymentDetailId,
                            Description          = x.PaymentDetail.Description,
                            LastCost             = x.PaymentDetail.LastCost,
                            PaintTaskDetailId    = x.PaintTaskDetailId,
                            PaymentCostHistoryId = x.PaymentDetail.PaymentCostHistorys.Any() ? x.PaymentDetail.PaymentCostHistorys.FirstOrDefault(z => z.EndDate == null).PaymentCostHistoryId : 0,
                            AreaPaintIn          = x.PaintWorkItem != null && x.PaintTaskDetailLayer == PaintTaskDetailLayer.Internal ?
                                                   (x.PaintWorkItem.IntArea ?? 0) * ((x.TaskDetailProgress ?? 0) / 100) : 0,
                            AreaPaintEx = x.PaintWorkItem != null && x.PaintTaskDetailLayer == PaintTaskDetailLayer.External ?
                                          (x.PaintWorkItem.IntArea ?? 0) * ((x.TaskDetailProgress ?? 0) / 100) : 0,
                        }).ToListAsync();

                        #endregion

                        #region BlastProgress
                        // get WorkLoad for paint team and project
                        var QueryBlastData = this.repositoryPaintTaskDetail.GetAllAsQueryable()
                                             .Where(x => x.BlastRoom.PaintTeamId == CurrentSubPayment.PaintTeamId &&
                                                    x.PaintTaskMaster.RequirePaintingList
                                                    .RequirePaintingMaster.ProjectCodeSub
                                                    .ProjectCodeMasterId == CurrentSubPayment.ProjectCodeMasterId &&
                                                    x.PaintTaskMaster.PaintTaskStatus != PaintTaskStatus.Cancel &&
                                                    x.PaymentDetailId != null &&
                                                    x.BlastWorkItemId != null)
                                             .Include(x => x.PaintTaskMaster)
                                             .Include(x => x.BlastRoom)
                                             .Include(x => x.BlastWorkItem)
                                             .Include(x => x.PaymentDetail.PaymentCostHistorys);

                        var DataBlast = await QueryBlastData.Select(x => new CalclateProgressViewModel
                        {
                            PaymentDetailId      = x.PaymentDetailId,
                            Description          = x.PaymentDetail.Description,
                            LastCost             = x.PaymentDetail.LastCost,
                            PaintTaskDetailId    = x.PaintTaskDetailId,
                            PaymentCostHistoryId = x.PaymentDetail.PaymentCostHistorys.Any() ? x.PaymentDetail.PaymentCostHistorys.FirstOrDefault(z => z.EndDate == null).PaymentCostHistoryId : 0,
                            AreaBlastIn          = x.BlastWorkItem != null && x.PaintTaskDetailLayer == PaintTaskDetailLayer.Internal ?
                                                   (x.BlastWorkItem.IntArea ?? 0) * ((x.TaskDetailProgress ?? 0) / 100) : 0,
                            AreaBlastEx = x.BlastWorkItem != null && x.PaintTaskDetailLayer == PaintTaskDetailLayer.External ?
                                          (x.BlastWorkItem.ExtArea ?? 0) * ((x.TaskDetailProgress ?? 0) / 100) : 0,
                        }).ToListAsync();

                        #endregion



                        var dbData = new List <CalclateProgressViewModel>();
                        dbData.AddRange(DataPaint.Where(x => x.AreaPaintEx > 0 || x.AreaPaintIn > 0));
                        dbData.AddRange(DataBlast.Where(x => x.AreaBlastEx > 0 || x.AreaBlastIn > 0));

                        if (dbData.Any())
                        {
                            Expression <Func <SubPaymentMaster, bool> > condition =
                                p => p.PaintTeamId == CurrentSubPayment.PaintTeamId &&
                                p.ProjectCodeMasterId == CurrentSubPayment.ProjectCodeMasterId;

                            // any subpayment for project and paint team
                            if (await this.repository.AnyDataAsync(condition))
                            {
                                var DbSubPayment = (await this.repositorySubPaymentDetail.GetAllAsQueryable()
                                                    .Where(x => x.SubPaymentMaster.PaintTeamId == CurrentSubPayment.PaintTeamId &&
                                                           x.SubPaymentMaster.ProjectCodeMasterId == CurrentSubPayment.ProjectCodeMasterId)
                                                    .GroupBy(x => x.PaymentDetailId)
                                                    .ToListAsync())
                                                   .Select(x => new
                                {
                                    PaymentDetailId = x.Key.Value,
                                    TotalArea       = x.Sum(z => z.AreaWorkLoad),
                                });

                                var SubPaymentDetails = dbData.GroupBy(x => x.PaymentDetailId)
                                                        .Select(x => new SubPaymentDetailViewModel
                                {
                                    AreaWorkLoad = DbSubPayment.FirstOrDefault(z => z.PaymentDetailId == x.Key) != null ?
                                                   x.Sum(y => (y.AreaBlastIn ?? 0) + (y.AreaBlastEx ?? 0) + (y.AreaPaintIn ?? 0) + (y.AreaPaintEx ?? 0)) -
                                                   (DbSubPayment.FirstOrDefault(z => z.PaymentDetailId == x.Key).TotalArea ?? 0) :
                                                   x.Sum(y => (y.AreaBlastIn ?? 0) + (y.AreaBlastEx ?? 0) + (y.AreaPaintIn ?? 0) + (y.AreaPaintEx ?? 0)),
                                    CurrentCost          = x.Average(y => y.LastCost),
                                    PaymentCostHistoryId = x.FirstOrDefault().PaymentCostHistoryId,
                                    PaymentDetailId      = x.Key,
                                    PaymentDetailString  = x.FirstOrDefault().Description ?? "-"
                                }).ToList();

                                return(new JsonResult(SubPaymentDetails.Where(x => x.AreaWorkLoad > 0), this.DefaultJsonSettings));
                            }
                            else
                            {
                                var SubPaymentDetails = dbData.GroupBy(x => x.PaymentDetailId)
                                                        .Select(x => new SubPaymentDetailViewModel
                                {
                                    AreaWorkLoad         = x.Sum(y => (y.AreaBlastIn ?? 0) + (y.AreaBlastEx ?? 0) + (y.AreaPaintIn ?? 0) + (y.AreaPaintEx ?? 0)),
                                    CurrentCost          = x.Average(y => y.LastCost),
                                    PaymentCostHistoryId = x.FirstOrDefault().PaymentCostHistoryId,
                                    PaymentDetailId      = x.Key,
                                    PaymentDetailString  = x.FirstOrDefault().Description ?? "-"
                                }).ToList();

                                return(new JsonResult(SubPaymentDetails, this.DefaultJsonSettings));
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                message = $"Has error {ex.ToString()}";
            }
            return(NotFound(new { Error = message }));
        }