private BundleUpdateViewModel GetBundleInitViewModel(Bundle selectedBundle)
        {
            var model = new BundleUpdateViewModel();
            var retriever = CategoryRetrieverFactory.GetInstance(_worldId);
            var categories =  retriever.GetCategories();
            
            using (var repository = RepositoryFactory.GetInstance(Session))
            {
                var newStatus = repository.FindClipStatuses().Single(x => x.Status == LessonStatus.New);
                var stringManager = new StringsManager(repository);
                var status = selectedBundle != null ? selectedBundle.Status.ObjectId : newStatus.ObjectId;
                var clipStatusName = selectedBundle.GetLocalizedPointerValue("status", "status");

                var teacherPublishingStatus = Session.GetLoggedInUser().GetPointerValue<ParseObject>("adminData", "userPublishingStatus").ObjectId;
                model.CategoryName1 = categories[0].Label;
                model.CategoryName2 = categories[1].Label;
                model.CategoryName3 = categories[2].Label;
                model.CategoryName4 = categories[3].Label;

                var emptyValue = new CategoryValuesDto
                {
                    Value_en_us = MyMentorResources.phSelecteCategory,
                    Value_he_il = MyMentorResources.phSelecteCategory,
                    Key = string.Empty
                };
                categories[0].Values.Insert(0, emptyValue);
                categories[1].Values.Insert(0, emptyValue);
                categories[2].Values.Insert(0, emptyValue);
                categories[3].Values.Insert(0, emptyValue);

                model.Category1Values = categories[0].Values.ToArray();
                model.Category2Values = categories[1].Values.ToArray();
                model.Category3Values = categories[2].Values.ToArray();
                model.Category4Values = categories[3].Values.ToArray();

                model.BundleTitleMask = stringManager.GetTemplate(_worldId, StringTemplates.BundleTitlePattern,Language.CurrentLanguageCode);
                model.LessonsExplanation = stringManager.GetLocalizedString(Strings.BundleLessonExplanation);
                model.StatusValues =repository.FindStatusOptionsByTeacherPublishingStatusAndClipStatus(teacherPublishingStatus, status,Session.GetLoggedInUserRoleName() == RoleNames.ADMINISTRATORS);

                if (selectedBundle != null)
                {
                    if (!model.StatusValues.Any(item => item.Key == selectedBundle.Status.ObjectId))
                    {
                        var statusValuesList = new List<KeyValuePair<string, string>>(model.StatusValues);
                        statusValuesList.Insert(0,
                            new KeyValuePair<string, string>(selectedBundle.Status.ObjectId, clipStatusName));
                        model.StatusValues = statusValuesList.ToArray();
                    }
                }
                return model;
            }
        }
 private static void SetClipViewModelInBunde(BundleUpdateViewModel model, Clip clipDetails, CurrencyDto sourceCurrency, CurrencyDto targetCurrency)
 {
     model.BundleClips.Add(new ClipMinimalData
     {
         Id = clipDetails.ObjectId,
         ClipNamePart1 = clipDetails.GetLocalizedField("portalNamePart1"),
         ClipNamePart2 = clipDetails.GetLocalizedField("portalNamePart2"),
         Price = CurrencyConverter.Convert(clipDetails.Price, sourceCurrency, targetCurrency).ToString("0.00"),
         Status = clipDetails.Status.GetLocalizedField("status"),
         Category3 = clipDetails.Category3.GetLocalizedField("value"),                
         Currency = clipDetails.Currency.ConvertToCurrencyDto()
     });
 }
        private async Task UpdateBundle(BundleUpdateViewModel model)
        {
            using (var repository = RepositoryFactory.GetInstance(Session))
            {
                var currencyRetriver = new CurrencyRetriver(HttpContext, Session, repository);
                var existingBundle = await repository.FindBundleById(model.ObjectId);
                var bundle = model.GetBundle();
                var activeStatusString =
                    repository.FindClipStatuses()
                        .Single(o => o.Status == LessonStatus.Active.ToLower())
                        .GetLocalizedField("status");

                var statusChanged = existingBundle.Status.ObjectId != bundle.Status.ObjectId;
                if (statusChanged)
                {
                    var hasInactiveClips = model.BundleClips.Any(o => o.Status != activeStatusString);
                    ClipStatus newStatus = null;
                    newStatus = Task.Run(() => bundle.Status.FetchIfNeededAsync()).Result;


                    if (newStatus.Status == LessonStatus.Active.ToLower())
                    {
                        if (hasInactiveClips)
                        {
                            throw new StatusChangeException(MyMentorResources.updateBundleInactiveLessonInBundle);
                        }
                    }
                }
                bundle.Currency = currencyRetriver.GetCurrent().ConvertToDomain();
                await repository.UpdateBundle(bundle);
            }
        }
 private async Task<string> AddBundle(BundleUpdateViewModel model, string worldContentTypeId)
 {
     using (var repository = RepositoryFactory.GetInstance(Session))
     {
         var currencyRetriver = new CurrencyRetriver(HttpContext, Session, repository);
         var bundle = model.GetBundle();
         bundle.Teacher = ParseObject.CreateWithoutData<ParseUser>(model.TeacherId);
         bundle.Currency = currencyRetriver.GetCurrent().ConvertToDomain();
         bundle.ContentType = new WorldContentType();
         bundle.ContentType.ObjectId = worldContentTypeId;
         return await repository.AddBundle(bundle);
     }
 }
 private static void ValidateBundlePrice(BundleUpdateViewModel model)
 {
     var bundleClipPrice = model.BundleClips.Sum(x => Convert.ToDouble(x.Price));
     var bundlePrice = Convert.ToDouble(model.Price);
     var discountOnClips = bundleClipPrice*0.9;
     if (bundlePrice > discountOnClips)
     {
         throw new BundlePriceException(MyMentorResources.bundlePriceLessThanClipsSum);
     }
 }
        public async Task<ActionResult> AddUpdateBundleData(BundleUpdateViewModel model)
        {
            var repository = RepositoryFactory.GetInstance(Session);
            try
            {
                var contentTypeRetriver = new WorldContentTypeRetriver(HttpContext,repository);
                var worldContentTypeId = contentTypeRetriver.GetWorldContentTypeId();

                var isNewBundle = model.ObjectId == null;
                var clipsIds = model.BundleClips.Select(o => o.Id).ToArray();
                if (!clipsIds.Any())
                {
                    return Json(new ServiceObjectResponse
                    {
                        Status = ServiceObjectResponse.Failure,
                        StatusReason = MyMentorResources.updateBundleNoLessonsSelected
                    });
                }

                ValidateBundlePrice(model);

                var teacher = await repository.FindUserByName(model.TeacherName);
                model.TeacherId = teacher.ObjectId;
                new NameManager(repository, Session).SetPortalBundleName(_worldId, model, teacher.ConvertToParseUserDto());

                if (isNewBundle)
                {
                    model.ObjectId = await AddBundle(model, worldContentTypeId);
                }
                else
                {
                    await UpdateBundle(model);
                }                
                lock (locker)
                {                    
                    Task.Run(() => repository.UpdateClipsInBundle(model.GetBundle(), clipsIds)).Wait();
                    var context = System.Web.HttpContext.Current;
                    new WebCacheProvider(context).ClearCachedItem(CacheKeys.ClipToBundle);                   
                }

                return Json(new ServiceObjectResponse
                {
                    Status = ServiceObjectResponse.Success,
                });
            }
            catch (Exception ex)
            {
                if (ex is DuplicateNameException ||
                    ex is StatusChangeException ||
                    ex is BundlePriceException)
                {
                    return Json(new ServiceObjectResponse
                    {
                        Status = ServiceObjectResponse.Failure,
                        StatusReason = ex.Message
                    });
                }

                mLogger.Log(LogLevel.Error, ex);
                return Json(new ServiceObjectResponse
                {
                    Status = ServiceObjectResponse.Failure,
                    StatusReason = MyMentorResources.errCanotAddBundleGeneral
                });
            }
            finally
            {
                repository.Dispose();
            }
        }