public IActionResult Index(string id)
        {
            var canAddNewCourse = _myCourseCtrl.CanAddNewCourseCatalog(User.Identity.Name, id);
            if(!canAddNewCourse) return View("Error");

            // HACK: Create tracking form
            var model = new PurchaseCourseViewModel { CourseId = id };
            return View(model);
        }
        public IActionResult Index(PurchaseCourseViewModel model)
        {
            if (ModelState.IsValid)
            {
                // HACK: Validate tracking form
                var selectedCourse = _courseCtrl.GetCourseDetail(model.CourseId);
                if (selectedCourse == null) return View("Error");

                var data = new PurchaseCourseConfirmViewModel(model)
                {
                    TotalChargeAmount = selectedCourse.Price
                };
                return View("Confirm", data);
            }
            return View(model);
        }
 public PurchaseCourseConfirmViewModel(PurchaseCourseViewModel data)
 {
     CourseId       = data.CourseId;
     CreditCardInfo = data.CreditCardInfo;
     PrimaryAddress = data.PrimaryAddress;
 }
 private Repositories.Models.Payment createNewPayment(string courseCatalogId, string courseName, string newSubscriptionId, PurchaseCourseViewModel model, double totalChargedAmount, DateTime currentTime, bool isPaymentSuccess)
 {
     var payment = new Repositories.Models.Payment
     {
         id = Guid.NewGuid().ToString(),
         FirstName = model.CreditCardInfo.FirstName,
         LastName = model.CreditCardInfo.LastName,
         Last4Digits = model.CreditCardInfo.LastFourDigits,
         CardType = model.CreditCardInfo.CardType.ToString(),
         CardNumber = APIUtil.EncodeCreditCard(model.CreditCardInfo.CardNumber),
         TotalChargedAmount = totalChargedAmount,
         BillingAddress = model.PrimaryAddress.Address,
         State = model.PrimaryAddress.State,
         City = model.PrimaryAddress.City,
         Country = model.PrimaryAddress.Country.ToString(),
         ZipCode = model.PrimaryAddress.ZipCode,
         CourseName = courseName,
         IsCompleted = isPaymentSuccess,
         CourseCatalogId = courseCatalogId,
         SubscriptionId = newSubscriptionId,
         CreatedDate = currentTime,
     };
     return payment;
 }
        public async Task<IActionResult> ChargeACreditCard(PurchaseCourseViewModel model)
        {
            try
            {
                var selectedUserProfile = _userprofileRepo.GetUserProfileById(User.Identity.Name);
                var isUserProfileValid = selectedUserProfile != null && !selectedUserProfile.DeletedDate.HasValue;
                if (!isUserProfileValid)
                {
                    _logger.LogCritical($"User profile { User.Identity.Name } not found.");
                    ViewBag.ErrorMessage = _errorMsgs.AccountNotFound;
                    return View("Error");
                }

                var selectedCourse = _courseCtrl.GetCourseDetail(model.CourseId);
                if (selectedCourse == null)
                {
                    ViewBag.ErrorMessage = _errorMsgs.CourseNotFound;
                    return View("Error");
                }

                var selectedClassRoom = _classRoomRepo.GetPublicClassRoomByCourseCatalogId(model.CourseId);
                var isClassRoomValid = selectedClassRoom != null && !selectedClassRoom.DeletedDate.HasValue;
                if (!isClassRoomValid)
                {
                    _logger.LogCritical($"ClassRoom of CourseId: { model.CourseId } not found.");
                    ViewBag.ErrorMessage = _errorMsgs.SelectedCourseIsNotAvailableForPurchase;
                    return View("Error");
                }

                var isAlreadyHaveTheSelectedCourse = !_myCourseCtrl.CanAddNewCourseCatalog(User.Identity.Name, model.CourseId);
                if (isAlreadyHaveTheSelectedCourse) return RedirectToAction("entercourse", "my", new { @id = model.CourseId });

                if (ModelState.IsValid)
                {
                    var paymentResult = Engines.Models.PaymentResult.Unknow;
                    var isPaymentSuccessed = false;
                    var newSubscriptionId = Guid.NewGuid().ToString();
                    var newPaymentId = string.Empty;
                    var now = _dateTime.GetCurrentTime();

                    try
                    {
                        // Pay with Paypal
                        paymentResult = _payment.ChargeCreditCard(new Engines.Models.PaymentInformation
                        {
                            Address = model.PrimaryAddress.Address,
                            City = model.PrimaryAddress.City,
                            Country = model.PrimaryAddress.Country.ToString(),
                            PostalCode = model.PrimaryAddress.ZipCode,
                            State = model.PrimaryAddress.State,
                            TotalPrice = selectedCourse.PriceUSD,
                            UserProfileId = User.Identity.Name,
                            PurchaseForCourseId = model.CourseId,
                            FirstName = model.CreditCardInfo.FirstName,
                            LastName = model.CreditCardInfo.LastName,
                            ExpiredYear = model.CreditCardInfo.ExpiredYear,
                            ExpiredMonth = model.CreditCardInfo.ExpiredMonth,
                            CVV = model.CreditCardInfo.CVV.ToString(),
                            CreditCardNumber = model.CreditCardInfo.CardNumber,
                            CardType = model.CreditCardInfo.CardType.ToString()
                        });
                    }
                    catch (Exception e)
                    {
                        _logger.LogError($"Paypal payment error, from user: { User.Identity.Name }, course id: { model.CourseId }, Error: { e.ToString() }");
                        ViewBag.ErrorMessage = _errorMsgs.CanNotChargeACreditCard;
                        return View("Error");
                    }
                    finally
                    {
                        isPaymentSuccessed = paymentResult == Engines.Models.PaymentResult.approved;
                        newSubscriptionId = isPaymentSuccessed ? newSubscriptionId : "None";
                        var payment = createNewPayment(selectedCourse.id, selectedCourse.SideName, newSubscriptionId, model, selectedCourse.PriceUSD, now, isPaymentSuccessed);
                        await _paymentRepo.CreateNewPayment(payment);
                        newPaymentId = payment.id;
                    }

                    if (!isPaymentSuccessed)
                    {
                        ViewBag.ErrorMessage = _errorMsgs.CanNotChargeACreditCard;
                        return View("Error");
                    }

                    try
                    {
                        var requestLessonCatalogIds = selectedClassRoom.Lessons.Select(it => it.LessonCatalogId);
                        var lessonCatalogs = _lessonCatalogRepo.GetLessonCatalogById(requestLessonCatalogIds).ToList();
                        var newClassCalendar = createClassCalendar(selectedClassRoom, lessonCatalogs, now);
                        newClassCalendar.CalculateCourseSchedule();
                        newClassCalendar.ExpiredDate = null;
                        selectedUserProfile.Subscriptions = addNewSelfPurchaseSubscription(selectedUserProfile.Subscriptions, selectedClassRoom, newClassCalendar.id, model.CourseId, now, newSubscriptionId);
                        var userActivity = selectedUserProfile.CreateNewUserActivity(selectedClassRoom, newClassCalendar, lessonCatalogs, now);

                        _classCalendarRepo.UpsertClassCalendar(newClassCalendar);
                        _userprofileRepo.UpsertUserProfile(selectedUserProfile);
                        _userActivityRepo.UpsertUserActivity(userActivity);

                        return RedirectToAction("Finished", new { @id = newPaymentId });
                    }
                    catch (Exception e)
                    {
                        _logger.LogCritical($"User: '******' already purchased course id: '{ model.CourseId }' with payment id: '{ newPaymentId }' but the system can't create new course.");
                        throw e;
                    }
                }
                return View(model);
            }
            catch (Exception e)
            {
                _logger.LogError($"MongoDB: { e.ToString() }");
                ViewBag.ErrorMessage = _errorMsgs.CanNotConnectToTheDatabase;
                return View("Error");
            }
        }
        public IActionResult Index(string id)
        {
            try
            {
                var selectedCourse = _courseCtrl.GetCourseDetail(id);
                if (selectedCourse == null)
                {
                    ViewBag.ErrorMessage = _errorMsgs.CourseNotFound;
                    return View("Error");
                }

                var selectedUserProfile = _userprofileRepo.GetUserProfileById(User.Identity.Name);
                if (selectedUserProfile == null)
                {
                    _logger.LogCritical($"User profile { User.Identity.Name } not found.");
                    ViewBag.ErrorMessage = _errorMsgs.AccountNotFound;
                    return View("Error");
                }

                var selectedClassRoom = _classRoomRepo.GetPublicClassRoomByCourseCatalogId(id);
                if (selectedClassRoom == null)
                {
                    _logger.LogCritical($"ClassRoom of CourseId: { id } not found.");
                    ViewBag.ErrorMessage = _errorMsgs.SelectedCourseIsNotAvailableForPurchase;
                    return View("Error");
                }

                var isAlreadyHaveTheSelectedCourse = !_myCourseCtrl.CanAddNewCourseCatalog(User.Identity.Name, id);
                if (isAlreadyHaveTheSelectedCourse) return RedirectToAction("entercourse", "my", new { @id = id });

                var model = new PurchaseCourseViewModel
                {
                    CourseId = id,
                    TotalChargeAmount = selectedCourse.PriceUSD
                };
                return View(model);
            }
            catch (Exception e)
            {
                _logger.LogError($"MongoDB: { e.ToString() }");
                ViewBag.ErrorMessage = _errorMsgs.CanNotConnectToTheDatabase;
                return View("Error");
            }
        }
 public PurchaseCourseConfirmViewModel(PurchaseCourseViewModel data)
 {
     CourseId = data.CourseId;
     CreditCardInfo = data.CreditCardInfo;
     PrimaryAddress = data.PrimaryAddress;
 }