public async Task <ActionResult> CommitPaymentForSessionAsync(PaymentViewModel viewModel)
        {
            ViewBag.ViewModel = viewModel;
            var profile = await HttpContext.GetUserAsync();

            var        lesson   = models.GetTable <RegisterLesson>().Where(r => r.RegisterID == viewModel.RegisterID).FirstOrDefault();
            LessonTime timeItem = null;

            if (lesson == null)
            {
                ModelState.AddModelError("RegisterID", "請選擇收款課程!!");
            }
            else
            {
                timeItem           = lesson.LessonTime.First();
                viewModel.SellerID = timeItem.BranchStore?.IsVirtualClassroom() == true
                    ? timeItem.AsAttendingCoach.SelectWorkBranchID()
                    : timeItem.BranchID.Value;
            }

            if (!viewModel.PayoffDate.HasValue)
            {
                ModelState.AddModelError("PayoffDate", "請選擇收款日期!!");
            }

            viewModel.ItemNo          = new string[] { "01" };
            viewModel.Brief           = new string[] { $"{timeItem.RegisterLesson.LessonPriceType.SimpleDescription}訓練費用" };
            viewModel.CostAmount      = new int?[] { viewModel.PayoffAmount };
            viewModel.UnitCost        = new int?[] { viewModel.PayoffAmount };
            viewModel.Piece           = new int?[] { 1 };
            viewModel.ItemRemark      = new string[] { null };
            viewModel.InvoiceType     = Naming.InvoiceTypeDefinition.一般稅額計算之電子發票;
            viewModel.CarrierId1      = viewModel.CarrierId1.GetEfficientString();
            viewModel.TransactionType = (int)Naming.PaymentTransactionType.自主訓練;

            if (viewModel.CarrierId1 != null)
            {
                if (viewModel.CarrierType == null)
                {
                    viewModel.CarrierType = "3J0002";
                }
            }

            var invoice = checkInvoiceNo(viewModel);

            if (String.IsNullOrEmpty(viewModel.PaymentType))
            {
                ModelState.AddModelError("PaymentType", "請選擇收款方式!!");
            }

            if (!viewModel.InvoiceType.HasValue)
            {
                ModelState.AddModelError("InvoiceType", "請選擇發票類型");
            }

            if (!ModelState.IsValid)
            {
                ViewBag.ModelState = ModelState;
                return(View(Startup.Properties["ReportInputError"]));
            }

            try
            {
                Payment item = models.GetTable <Payment>()
                               .Where(p => p.PaymentID == viewModel.PaymentID).FirstOrDefault();

                if (item == null)
                {
                    item = new Payment
                    {
                        Status             = (int)Naming.CourseContractStatus.已生效,
                        TuitionInstallment = new TuitionInstallment
                        {
                        },
                        PaymentTransaction = new PaymentTransaction
                        {
                        },
                        PaymentAudit = new Models.DataEntity.PaymentAudit {
                        }
                    };
                    item.TuitionAchievement.Add(new TuitionAchievement
                    {
                        CoachID        = lesson.AdvisorID.Value,
                        ShareAmount    = viewModel.PayoffAmount,
                        CoachWorkPlace = lesson.ServingCoach.WorkBranchID()
                    });
                    models.GetTable <Payment>().InsertOnSubmit(item);
                    item.InvoiceItem = invoice;
                }
                item.TuitionInstallment.RegisterID   = lesson.IntuitionCharge.RegisterID;
                item.TuitionInstallment.PayoffAmount = viewModel.PayoffAmount;
                item.TuitionInstallment.PayoffDate   = viewModel.PayoffDate;

                item.PaymentTransaction.BranchID = viewModel.SellerID.Value;

                preparePayment(viewModel, profile, item);

                models.SubmitChanges();

                if (timeItem.IsPISession())
                {
                    models.AttendLesson(lesson.LessonTime.First(), profile);
                }

                if (invoice.InvoiceCarrier != null && viewModel.MyCarrier == true)
                {
                    lesson.UserProfile.UserProfileExtension.CarrierType = invoice.InvoiceCarrier.CarrierType;
                    lesson.UserProfile.UserProfileExtension.CarrierNo   = invoice.InvoiceCarrier.CarrierNo;
                    models.SubmitChanges();
                }

                TaskExtensionMethods.ProcessInvoiceToGov();

                return(Content(new { result = true, invoiceNo = item.InvoiceItem.TrackCode + item.InvoiceItem.No, item.InvoiceID, item.InvoiceItem.InvoiceType, item.PaymentID }.JsonStringify(), "application/json"));
            }
            catch (Exception ex)
            {
                ApplicationLogging.CreateLogger <PaymentConsoleController>()
                .LogError(ex, ex.Message);
                return(Json(new { result = false, message = ex.Message }));
            }
        }
        public async Task <ActionResult> UpdateBookingByCoach(LessonTimeViewModel viewModel)
        {
            ViewBag.ViewModel = viewModel;
            var profile = await HttpContext.GetUserAsync();

            if (viewModel.KeyID != null)
            {
                viewModel.LessonID = viewModel.DecryptKeyValue();
            }

            LessonTime item = models.GetTable <LessonTime>().Where(l => l.LessonID == viewModel.LessonID).FirstOrDefault();

            if (item == null)
            {
                return(View("~/Views/Shared/JsAlert.cshtml", model: "修改上課時間資料不存在!!"));
            }

            if (item.LessonAttendance != null)
            {
                return(View("~/Views/ConsoleHome/Shared/JsAlert.cshtml", model: "已完成上課,不可修改!!"));
            }

            if (item.ContractTrustTrack.Any(t => t.SettlementID.HasValue))
            {
                return(View("~/Views/ConsoleHome/Shared/JsAlert.cshtml", model: "課程資料已信託,不可修改!!"));
            }

            var coach = models.GetTable <ServingCoach>().Where(c => c.CoachID == viewModel.CoachID).FirstOrDefault();

            if (coach == null)
            {
                return(View("~/Views/ConsoleHome/Shared/JsAlert.cshtml", model: "上課教練資料錯誤!!"));
            }

            if (!viewModel.ClassDate.HasValue)
            {
                return(View("~/Views/ConsoleHome/Shared/JsAlert.cshtml", model: "請選擇上課日期間!!"));
            }

            if (!item.BranchStore.IsVirtualClassroom() && !item.IsSTSession() && !models.GetTable <CoachWorkplace>()
                .Any(c => c.BranchID == item.BranchID &&
                     c.CoachID == item.AttendingCoach) &&
                viewModel.ClassDate.Value < DateTime.Today.AddDays(1))
            {
                return(View("~/Views/ConsoleHome/Shared/JsAlert.cshtml", model: "此時段不允許跨店預約!!"));
            }


            LessonTime timeItem = new LessonTime
            {
                InvitedCoach      = item.InvitedCoach,
                AttendingCoach    = item.AttendingCoach,
                ClassTime         = viewModel.ClassDate,
                DurationInMinutes = item.DurationInMinutes
            };

            if (item.IsPTSession())
            {
                if (models.GetTable <Settlement>().Any(s => s.StartDate <= viewModel.ClassDate && s.EndExclusiveDate > viewModel.ClassDate))
                {
                    ViewBag.Message = "修改上課時間(" + String.Format("{0:yyyy/MM/dd}", viewModel.ClassDate) + "已信託結算!!";
                    return(View("~/Views/ConsoleHome/Shared/JsAlert.cshtml"));
                }
            }

            if (!item.IsCoachPISession() && !item.IsSTSession())
            {
                var users = models.CheckOverlappingBooking(timeItem, item);
                if (users.Count() > 0)
                {
                    ViewBag.Message = "上課成員(" + String.Join("、", users.Select(u => u.RealName)) + ")上課時間重複!!";
                    return(View("~/Views/ConsoleHome/Shared/JsAlert.cshtml"));
                }
            }
            else
            {
                if (viewModel.ClassEndTime.HasValue)
                {
                    timeItem.DurationInMinutes =
                        (int)(viewModel.ClassEndTime.Value - viewModel.ClassDate.Value).TotalMinutes;
                }
            }

            if (!ModelState.IsValid)
            {
                ViewBag.ModelState = this.ModelState;
                return(View(Startup.Properties["ReportInputError"]));
            }

            var changeCoach = item.AttendingCoach != viewModel.CoachID;

            if (item.IsCoachPISession())
            {
                if (viewModel.AttendeeID == null || viewModel.AttendeeID.Length == 0)
                {
                    models.DeleteAll <LessonTime>(r => r.LessonID != item.LessonID && r.GroupID == item.GroupID);
                    models.DeleteAll <RegisterLesson>(r => r.RegisterID != item.RegisterID && r.RegisterGroupID == item.GroupID);
                }
                else
                {
                    models.DeleteAll <LessonTime>(r => r.LessonID != item.LessonID && r.GroupID == item.GroupID &&
                                                  !viewModel.AttendeeID.Contains(r.AttendingCoach.Value));
                    models.DeleteAll <RegisterLesson>(r => r.RegisterID != item.RegisterID && r.RegisterGroupID == item.GroupID &&
                                                      !viewModel.AttendeeID.Contains(r.UID));
                    foreach (var uid in viewModel.AttendeeID.Distinct())
                    {
                        if (!models.GetTable <RegisterLesson>().Any(r => r.UID == uid && r.RegisterGroupID == item.GroupID))
                        {
                            var coachPI = models.GetTable <ServingCoach>().Any(s => s.CoachID == uid)
                                    ? LessonsController.SpawnCoachPI(item, uid, uid)
                                    : LessonsController.SpawnCoachPI(item, uid, coach.CoachID);
                            models.GetTable <LessonTime>().InsertOnSubmit(coachPI);
                        }
                    }
                }

                models.SubmitChanges();

                foreach (var s in models.GetTable <LessonTime>().Where(l => l.GroupID == item.GroupID))
                {
                    s.ClassTime = viewModel.ClassDate;
                    if (models.GetTable <DailyWorkingHour>().Any(d => d.Hour == viewModel.ClassDate.Value.Hour))
                    {
                        s.HourOfClassTime = viewModel.ClassDate.Value.Hour;
                    }

                    s.DurationInMinutes = timeItem.DurationInMinutes;
                    s.BranchID          = viewModel.BranchID;

                    //item.TrainingBySelf = viewModel.TrainingBySelf;
                }
            }
            else
            {
                item.InvitedCoach = viewModel.CoachID;
                item.AssignLessonAttendingCoach(coach);
                item.ClassTime = viewModel.ClassDate;
                if (models.GetTable <DailyWorkingHour>().Any(d => d.Hour == viewModel.ClassDate.Value.Hour))
                {
                    item.HourOfClassTime = viewModel.ClassDate.Value.Hour;
                }

                item.DurationInMinutes = timeItem.DurationInMinutes;
                item.BranchID          = viewModel.BranchID;
                foreach (var t in item.ContractTrustTrack)
                {
                    t.EventDate = viewModel.ClassDate.Value;
                }
                //item.TrainingBySelf = viewModel.TrainingBySelf;
            }

            models.SubmitChanges();

            if (item.IsPISession())
            {
                models.ExecuteCommand("update TuitionInstallment set PayoffDate = {0} where RegisterID = {1} ", item.ClassTime, item.RegisterID);
            }

            if (!item.IsSTSession())
            {
                item.BookingLessonTimeExpansion(models, item.ClassTime.Value, item.DurationInMinutes.Value);

                models.ExecuteCommand("delete PreferredLessonTime where LessonID = {0}", item.LessonID);
                item.ProcessBookingWhenCrossBranch(models);
            }

            return(Json(new
            {
                result = true,
                message = "上課時間修改完成!!",
                changeCoach = changeCoach,
                classTime = String.Format("{0:yyyy/MM/dd H:mm}", item.ClassTime) + "-" + String.Format("{0:H:mm}", item.ClassTime.Value.AddMinutes(item.DurationInMinutes.Value))
            }));
        }