public ActionResult SubscribeNewsletter(bool subscribe, string email)
        {
            string result;
            bool success = false;

			if (!email.IsEmail())
                result = _localizationService.GetResource("Newsletter.Email.Wrong");
            else
            {
                //subscribe/unsubscribe
                email = email.Trim();

                var subscription = _newsLetterSubscriptionService.GetNewsLetterSubscriptionByEmail(email);
                if (subscription != null)
                {
                    if (subscribe)
                    {
                        if (!subscription.Active)
                        {
                            _workflowMessageService.SendNewsLetterSubscriptionActivationMessage(subscription, _workContext.WorkingLanguage.Id);
                        }
                        result = _localizationService.GetResource("Newsletter.SubscribeEmailSent");
                    }
                    else
                    {
                        if (subscription.Active)
                        {
                            _workflowMessageService.SendNewsLetterSubscriptionDeactivationMessage(subscription, _workContext.WorkingLanguage.Id);
                        }
                        result = _localizationService.GetResource("Newsletter.UnsubscribeEmailSent");
                    }
                }
                else if (subscribe)
                {
                    subscription = new NewsLetterSubscription()
                    {
                        NewsLetterSubscriptionGuid = Guid.NewGuid(),
                        Email = email,
                        Active = false,
                        CreatedOnUtc = DateTime.UtcNow
                    };
                    _newsLetterSubscriptionService.InsertNewsLetterSubscription(subscription);
                    _workflowMessageService.SendNewsLetterSubscriptionActivationMessage(subscription, _workContext.WorkingLanguage.Id);

                    result = _localizationService.GetResource("Newsletter.SubscribeEmailSent");
                }
                else
                {
                    result = _localizationService.GetResource("Newsletter.UnsubscribeEmailSent");
                }
                success = true;
            }

            return Json(new
            {
                Success = success,
                Result = result,
            });
        }
        public void VerifyDeleteTriggersUnsubscribeEvent()
        {
			var subscription = new NewsLetterSubscription { Active = true, Email = "*****@*****.**", StoreId = 1 };

			_newsLetterSubscriptionService.DeleteNewsLetterSubscription(subscription, true);

            _eventPublisher.AssertWasCalled(x => x.Publish(new EmailUnsubscribedEvent(subscription.Email)));
        }
        /// <summary>
        /// Deletes a newsletter subscription
        /// </summary>
        /// <param name="newsLetterSubscription">NewsLetter subscription</param>
        /// <param name="publishSubscriptionEvents">if set to <c>true</c> [publish subscription events].</param>
        public virtual void DeleteNewsLetterSubscription(NewsLetterSubscription newsLetterSubscription, bool publishSubscriptionEvents = true)
        {
            if (newsLetterSubscription == null) throw new ArgumentNullException("newsLetterSubscription");

            _subscriptionRepository.Delete(newsLetterSubscription);

            //Publish the unsubscribe event
            PublishSubscriptionEvent(newsLetterSubscription.Email, false, publishSubscriptionEvents);

            //event notification
            _eventPublisher.EntityDeleted(newsLetterSubscription);
        }
        public void VerifyInactiveToActiveUpdateTriggersSubscribeEvent()
        {
            //Prepare the original result
			var originalSubscription = new NewsLetterSubscription { Active = false, Email = "*****@*****.**", StoreId = 1 };
			_subscriptionRepository.Stub(m => m.GetById(Arg<object>.Is.Anything)).Return(originalSubscription);

			var subscription = new NewsLetterSubscription { Active = true, Email = "*****@*****.**", StoreId = 1 };

            _newsLetterSubscriptionService.UpdateNewsLetterSubscription(subscription, true);

            _eventPublisher.AssertWasCalled(x => x.Publish(new EmailSubscribedEvent(subscription.Email)));
        }
        public void VerifyDeleteTriggersUnsubscribeEvent()
        {
            var eventPublisher = MockRepository.GenerateStub<IEventPublisher>();
            var repo = MockRepository.GenerateStub<IRepository<NewsLetterSubscription>>();
            var context = MockRepository.GenerateStub<IDbContext>();

            var subscription = new NewsLetterSubscription { Active = true, Email = "*****@*****.**" };

            var service = new NewsLetterSubscriptionService(context, repo, eventPublisher);
            service.DeleteNewsLetterSubscription(subscription, true);

            eventPublisher.AssertWasCalled(x => x.Publish(new EmailUnsubscribedEvent(subscription.Email)));
        }
        public void VerifyEmailUpdateTriggersUnsubscribeAndSubscribeEvent()
        {
            var eventPublisher = MockRepository.GenerateStub<IEventPublisher>();
            var repo = MockRepository.GenerateStub<IRepository<NewsLetterSubscription>>();
            var context = MockRepository.GenerateStub<IDbContext>();

            //Prepare the original result
            var originalSubscription = new NewsLetterSubscription { Active = true, Email = "*****@*****.**" };
            repo.Stub(m => m.GetById(Arg<object>.Is.Anything)).Return(originalSubscription);

            var subscription = new NewsLetterSubscription { Active = true, Email = "*****@*****.**" };

            var service = new NewsLetterSubscriptionService(context, repo, eventPublisher);
            service.UpdateNewsLetterSubscription(subscription, true);

            eventPublisher.AssertWasCalled(x => x.Publish(new EmailUnsubscribedEvent(originalSubscription.Email)));
            eventPublisher.AssertWasCalled(x => x.Publish(new EmailSubscribedEvent(subscription.Email)));
        }
        public void Can_save_and_load_nls()
        {
            var newGuid = Guid.NewGuid();
            var now = new DateTime(2010, 01, 01);

            var nls = new NewsLetterSubscription
            {
                Email = "*****@*****.**",
                NewsLetterSubscriptionGuid = newGuid,
                CreatedOnUtc = now,
                Active = true
            };

            var fromDb = SaveAndLoadEntity(nls);
            fromDb.ShouldNotBeNull();
            fromDb.Email.ShouldEqual("*****@*****.**");
            fromDb.NewsLetterSubscriptionGuid.ShouldEqual(newGuid);
            fromDb.CreatedOnUtc.ShouldEqual(now);
            fromDb.Active.ShouldBeTrue();
        }
        public virtual void AddNewsLetterSubscriptionTokens(IList<Token> tokens, NewsLetterSubscription subscription)
        {
            tokens.Add(new Token("NewsLetterSubscription.Email", subscription.Email));

            const string urlFormat = "{0}newsletter/subscriptionactivation/{1}/{2}";

            var activationUrl = String.Format(urlFormat, _webHelper.GetStoreLocation(false), subscription.NewsLetterSubscriptionGuid, "true");
            tokens.Add(new Token("NewsLetterSubscription.ActivationUrl", activationUrl, true));

            var deActivationUrl = String.Format(urlFormat, _webHelper.GetStoreLocation(false), subscription.NewsLetterSubscriptionGuid, "false");
            tokens.Add(new Token("NewsLetterSubscription.DeactivationUrl", deActivationUrl, true));

            //event notification
            _eventPublisher.EntityTokensAdded(subscription, tokens);
        }
        /// <summary>
        /// Sends a newsletter subscription deactivation message
        /// </summary>
        /// <param name="subscription">Newsletter subscription</param>
        /// <param name="languageId">Language identifier</param>
        /// <returns>Queued email identifier</returns>
        public virtual int SendNewsLetterSubscriptionDeactivationMessage(NewsLetterSubscription subscription,
            int languageId)
        {
            if (subscription == null)
                throw new ArgumentNullException("subscription");

			var store = _storeContext.CurrentStore;
			languageId = EnsureLanguageIsActive(languageId, store.Id);
			
            var messageTemplate = GetLocalizedActiveMessageTemplate("NewsLetterSubscription.DeactivationMessage", languageId, store.Id);
            if (messageTemplate == null)
                return 0;

			var tokens = new List<Token>();
			_messageTokenProvider.AddStoreTokens(tokens, _storeContext.CurrentStore);
            _messageTokenProvider.AddNewsLetterSubscriptionTokens(tokens, subscription);

            //event notification
            _eventPublisher.MessageTokensAdded(messageTemplate, tokens);

            var emailAccount = GetEmailAccountOfMessageTemplate(messageTemplate, languageId);
            var toEmail = subscription.Email;
            var toName = "";
            return SendNotification(messageTemplate, emailAccount,
                languageId, tokens,
                toEmail, toName);
        }
        public ImportResult ImportSubscribers(Stream stream)
        {
            Guard.ArgumentNotNull(() => stream);

            var result = new ImportResult();
            var toAdd = new List<NewsLetterSubscription>();
            var toUpdate = new List<NewsLetterSubscription>();
            var autoCommit = _subscriptionRepository.AutoCommitEnabled;
            var validateOnSave = _subscriptionRepository.Context.ValidateOnSaveEnabled;
            var autoDetectChanges = _subscriptionRepository.Context.AutoDetectChangesEnabled;
            var proxyCreation = _subscriptionRepository.Context.ProxyCreationEnabled;

            try
            {
                using (var reader = new StreamReader(stream))
                {
                    _subscriptionRepository.Context.ValidateOnSaveEnabled = false;
                    _subscriptionRepository.Context.AutoDetectChangesEnabled = false;
                    _subscriptionRepository.Context.ProxyCreationEnabled = false;
                    
                    while (!reader.EndOfStream)
                    {
                        string line = reader.ReadLine();
                        if (line.IsEmpty())
                        {
                            continue;
                        }
                        string[] tmp = line.Split(',');

                        var email = "";
                        bool isActive = true;
						int storeId = 0;

                        // parse
                        if (tmp.Length == 1)
                        {
                            // "email" only
                            email = tmp[0].Trim();
                        }
                        else if (tmp.Length == 2)
                        {
                            // "email" and "active" fields specified
                            email = tmp[0].Trim();
                            isActive = Boolean.Parse(tmp[1].Trim());
                        }
						else if (tmp.Length == 3)
						{
							email = tmp[0].Trim();
							isActive = Boolean.Parse(tmp[1].Trim());
							storeId = int.Parse(tmp[2].Trim());
						}
						else
						{
							throw new SmartException("Wrong file format (expected comma separated entries 'Email' and optionally 'IsActive')");
						}

                        result.TotalRecords++;

                        if (email.Length > 255)
                        {
                            result.AddWarning("The emal address '{0}' exceeds the maximun allowed length of 255.".FormatInvariant(email));
                            continue;
                        }

                        if (!email.IsEmail())
                        {
							result.AddWarning("'{0}' is not a valid email address.".FormatInvariant(email));
                            continue;
                        }

						if (storeId == 0)
						{
							storeId = _storeService.GetAllStores().First().Id;
						}

                        // import
                        var subscription = (from nls in _subscriptionRepository.Table
                                            where nls.Email == email && nls.StoreId == storeId
                                            orderby nls.Id
                                            select nls).FirstOrDefault();

                        if (subscription != null)
                        {
                            subscription.Active = isActive;

                            toUpdate.Add(subscription);
                            result.ModifiedRecords++;
                        }
                        else
                        {
                            subscription = new NewsLetterSubscription()
                            {
                                Active = isActive,
                                CreatedOnUtc = DateTime.UtcNow,
                                Email = email,
                                NewsLetterSubscriptionGuid = Guid.NewGuid(),
								StoreId = storeId
                            };

                            toAdd.Add(subscription);
                            result.NewRecords++;
                        }
                    }
                }

                // insert new subscribers
                _subscriptionRepository.AutoCommitEnabled = true;
                _subscriptionRepository.InsertRange(toAdd, 500);
                toAdd.Clear();

                // update modified subscribers
                _subscriptionRepository.AutoCommitEnabled = false;
                toUpdate.Each(x => 
                {
                    _subscriptionRepository.Update(x);
                });
                _subscriptionRepository.Context.SaveChanges();
                toUpdate.Clear();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                _subscriptionRepository.AutoCommitEnabled = autoCommit;
                _subscriptionRepository.Context.ValidateOnSaveEnabled = validateOnSave;
                _subscriptionRepository.Context.AutoDetectChangesEnabled = autoDetectChanges;
                _subscriptionRepository.Context.ProxyCreationEnabled = proxyCreation;
            }

            return result;
        }
        /// <summary>
        /// Updates a newsletter subscription
        /// </summary>
        /// <param name="newsLetterSubscription">NewsLetter subscription</param>
        /// <param name="publishSubscriptionEvents">if set to <c>true</c> [publish subscription events].</param>
        public void UpdateNewsLetterSubscription(NewsLetterSubscription newsLetterSubscription, bool publishSubscriptionEvents = true)
        {
            if (newsLetterSubscription == null)
            {
                throw new ArgumentNullException("newsLetterSubscription");
            }

			if (newsLetterSubscription.StoreId == 0)
			{
				throw new SmartException("News letter subscription must be assigned to a valid store.");
			}

            //Handle e-mail
            newsLetterSubscription.Email = EnsureSubscriberEmailOrThrow(newsLetterSubscription.Email);

            //Get original subscription record
            var originalSubscription = _context.LoadOriginalCopy(newsLetterSubscription);

            //Persist
            _subscriptionRepository.Update(newsLetterSubscription);

            //Publish the subscription event 
            if ((originalSubscription.Active == false && newsLetterSubscription.Active) ||
                (newsLetterSubscription.Active && (originalSubscription.Email != newsLetterSubscription.Email)))
            {
                //If the previous entry was false, but this one is true, publish a subscribe.
                PublishSubscriptionEvent(newsLetterSubscription.Email, true, publishSubscriptionEvents);
            }
            
            if ((originalSubscription.Active && newsLetterSubscription.Active) && 
                (originalSubscription.Email != newsLetterSubscription.Email))
            {
                //If the two emails are different publish an unsubscribe.
                PublishSubscriptionEvent(originalSubscription.Email, false, publishSubscriptionEvents);
            }

            if ((originalSubscription.Active && !newsLetterSubscription.Active))
            {
                //If the previous entry was true, but this one is false
                PublishSubscriptionEvent(originalSubscription.Email, false, publishSubscriptionEvents);
            }

            //Publish event
            _eventPublisher.EntityUpdated(newsLetterSubscription);
        }
        /// <summary>
        /// Inserts a newsletter subscription
        /// </summary>
        /// <param name="newsLetterSubscription">NewsLetter subscription</param>
        /// <param name="publishSubscriptionEvents">if set to <c>true</c> [publish subscription events].</param>
        public void InsertNewsLetterSubscription(NewsLetterSubscription newsLetterSubscription, bool publishSubscriptionEvents = true)
        {
            if (newsLetterSubscription == null)
            {
                throw new ArgumentNullException("newsLetterSubscription");
            }

			if (newsLetterSubscription.StoreId == 0)
			{
				throw new SmartException("News letter subscription must be assigned to a valid store.");
			}

            //Handle e-mail
            newsLetterSubscription.Email = EnsureSubscriberEmailOrThrow(newsLetterSubscription.Email);

            //Persist
            _subscriptionRepository.Insert(newsLetterSubscription);

            //Publish the subscription event 
            if (newsLetterSubscription.Active)
            {
                PublishSubscriptionEvent(newsLetterSubscription.Email, true, publishSubscriptionEvents);
            }

            //Publish event
            _eventPublisher.EntityInserted(newsLetterSubscription);
        }
 public static NewsLetterSubscription ToEntity(this NewsLetterSubscriptionModel model, NewsLetterSubscription destination)
 {
     return Mapper.Map(model, destination);
 }
        public void VerifyUpdateEventIsFired()
        {
            //Prepare the original result
			var originalSubscription = new NewsLetterSubscription { Active = false, Email = "*****@*****.**", StoreId = 1 };
			_subscriptionRepository.Stub(m => m.GetById(Arg<object>.Is.Anything)).Return(originalSubscription);

			_newsLetterSubscriptionService.UpdateNewsLetterSubscription(new NewsLetterSubscription { Email = "*****@*****.**", StoreId = 1 });

            _eventPublisher.AssertWasCalled(x => x.EntityUpdated(Arg<NewsLetterSubscription>.Is.Anything));
        }
        public void VerifyUpdateEventIsFired()
        {
            var eventPublisher = MockRepository.GenerateStub<IEventPublisher>();
            var repo = MockRepository.GenerateStub<IRepository<NewsLetterSubscription>>();
            var context = MockRepository.GenerateStub<IDbContext>();

            //Prepare the original result
            var originalSubscription = new NewsLetterSubscription { Active = false, Email = "*****@*****.**" };
            repo.Stub(m => m.GetById(Arg<object>.Is.Anything)).Return(originalSubscription);

            var service = new NewsLetterSubscriptionService(context, repo, eventPublisher);
            service.UpdateNewsLetterSubscription(new NewsLetterSubscription { Email = "*****@*****.**" });

            eventPublisher.AssertWasCalled(x => x.EntityUpdated(Arg<NewsLetterSubscription>.Is.Anything));
        }
        public void Execute(ImportExecuteContext context)
        {
            var utcNow = DateTime.UtcNow;
            var currentStoreId = _services.StoreContext.CurrentStore.Id;

            using (var scope = new DbContextScope(ctx: _services.DbContext, autoDetectChanges: false, proxyCreation: false, validateOnSave: false, autoCommit: false))
            {
                var segmenter = context.DataSegmenter;

                context.Result.TotalRecords = segmenter.TotalRows;

                while (context.Abort == DataExchangeAbortion.None && segmenter.ReadNextBatch())
                {
                    var batch = segmenter.GetCurrentBatch<NewsLetterSubscription>();

                    // Perf: detach all entities
                    _subscriptionRepository.Context.DetachEntities<NewsLetterSubscription>(false);

                    context.SetProgress(segmenter.CurrentSegmentFirstRowIndex - 1, segmenter.TotalRows);

                    foreach (var row in batch)
                    {
                        try
                        {
                            var active = true;
                            var email = row.GetDataValue<string>("Email");
                            var storeId = row.GetDataValue<int>("StoreId");

                            if (storeId == 0)
                            {
                                storeId = currentStoreId;
                            }

                            if (row.HasDataValue("Active") && row.TryGetDataValue("Active", out active))
                            {
                            }
                            else
                            {
                                active = true;	// default
                            }

                            if (email.IsEmpty())
                            {
                                context.Result.AddWarning("Skipped empty email address", row.GetRowInfo(), "Email");
                                continue;
                            }

                            if (email.Length > 255)
                            {
                                context.Result.AddWarning("Skipped email address '{0}'. It exceeds the maximum allowed length of 255".FormatInvariant(email), row.GetRowInfo(), "Email");
                                continue;
                            }

                            if (!email.IsEmail())
                            {
                                context.Result.AddWarning("Skipped invalid email address '{0}'".FormatInvariant(email), row.GetRowInfo(), "Email");
                                continue;
                            }

                            NewsLetterSubscription subscription = null;

                            foreach (var keyName in context.KeyFieldNames)
                            {
                                switch (keyName)
                                {
                                    case "Email":
                                        subscription = _subscriptionRepository.Table
                                            .OrderBy(x => x.Id)
                                            .FirstOrDefault(x => x.Email == email && x.StoreId == storeId);
                                        break;
                                }

                                if (subscription != null)
                                    break;
                            }

                            if (subscription == null)
                            {
                                if (context.UpdateOnly)
                                {
                                    ++context.Result.SkippedRecords;
                                    continue;
                                }

                                subscription = new NewsLetterSubscription
                                {
                                    Active = active,
                                    CreatedOnUtc = utcNow,
                                    Email = email,
                                    NewsLetterSubscriptionGuid = Guid.NewGuid(),
                                    StoreId = storeId
                                };

                                _subscriptionRepository.Insert(subscription);
                                context.Result.NewRecords++;
                            }
                            else
                            {
                                subscription.Active = active;

                                _subscriptionRepository.Update(subscription);
                                context.Result.ModifiedRecords++;
                            }
                        }
                        catch (Exception exception)
                        {
                            context.Result.AddError(exception.ToAllMessages(), row.GetRowInfo());
                        }
                    } // for

                    _subscriptionRepository.Context.SaveChanges();
                } // while
            }
        }