Пример #1
0
        public void Execute(ExecutingProcess executingProcess)
        {
            NewsletterEntity newsletter = (NewsletterEntity)executingProcess.Data;

            var queryName = QueryLogic.ToQueryName(newsletter.Query.Key);

            QueryDescription qd = DynamicQueryManager.Current.QueryDescription(queryName);

            List <QueryToken> list = new List <QueryToken>();

            using (ExecutionMode.Global())
            {
                list.Add(QueryUtils.Parse("Entity", qd, 0));
                list.Add(QueryUtils.Parse(".".Combine("Entity", "NewsletterDeliveries", "Element"), qd, SubTokensOptions.CanElement));
                list.Add(QueryUtils.Parse(".".Combine("Entity", "EmailOwnerData"), qd, 0));

                EmailTemplateParser.Parse(newsletter.Subject, qd, null).FillQueryTokens(list);
                EmailTemplateParser.Parse(newsletter.Text, qd, null).FillQueryTokens(list);

                list = list.Distinct().ToList();
            }

            var columns = list.Select(qt => new Column(qt, null)).ToList();

            //var columns = new List<QueryToken>();
            //columns.Add(QueryUtils.Parse("Entity.NewsletterDeliveries.Element", qd, canAggregate: false));
            //columns.Add(QueryUtils.Parse("Entity.Email", qd, canAggregate: false));
            //columns.AddRange(NewsletterLogic.GetTokens(queryName, newsletter.Subject));
            //columns.AddRange(NewsletterLogic.GetTokens(queryName, newsletter.Text));

            columns = columns.Distinct().ToList();

            var resultTable = DynamicQueryManager.Current.ExecuteQuery(new QueryRequest
            {
                QueryName = queryName,
                Filters   = new List <Filter>
                {
                    new Filter(QueryUtils.Parse("Entity.NewsletterDeliveries.Element.Newsletter", qd, SubTokensOptions.CanElement), FilterOperation.EqualTo, newsletter.ToLite()),
                    new Filter(QueryUtils.Parse("Entity.NewsletterDeliveries.Element.Sent", qd, SubTokensOptions.CanElement), FilterOperation.EqualTo, false),
                },
                Orders     = new List <Order>(),
                Columns    = columns,
                Pagination = new Pagination.All(),
            });

            var dicTokenColumn = resultTable.Columns.ToDictionary(rc => rc.Column.Token);

            var entityColumn     = resultTable.Columns.SingleEx(c => c.Column.Token.FullKey() == "Entity");
            var deliveryColumn   = resultTable.Columns.SingleEx(c => c.Column.Token.FullKey() == "Entity.NewsletterDeliveries.Element");
            var emailOwnerColumn = resultTable.Columns.SingleEx(c => c.Column.Token.FullKey() == "Entity.EmailOwnerData");

            var lines = resultTable.Rows.GroupBy(r => (Lite <Entity>)r[entityColumn]).Select(g => new SendLine
            {
                NewsletterDelivery = (Lite <NewsletterDeliveryEntity>)g.DistinctSingle(deliveryColumn),
                Email = (EmailOwnerData)g.DistinctSingle(emailOwnerColumn),
                Rows  = g,
            }).ToList();

            if (newsletter.SubjectParsedNode == null)
            {
                newsletter.SubjectParsedNode = EmailTemplateParser.Parse(newsletter.Subject, qd, null);
            }

            if (newsletter.TextParsedNode == null)
            {
                newsletter.TextParsedNode = EmailTemplateParser.Parse(newsletter.Text, qd, null);
            }

            var conf = EmailLogic.Configuration;

            int processed = 0;

            foreach (var group in lines.GroupsOf(20))
            {
                processed += group.Count;

                executingProcess.CancellationToken.ThrowIfCancellationRequested();

                if (conf.SendEmails)
                {
                    Parallel.ForEach(group, s =>
                    {
                        try
                        {
                            var smtpConfig = NewsletterLogic.GetStmpConfiguration(newsletter);

                            var client  = smtpConfig.GenerateSmtpClient();
                            var message = new MailMessage();

                            if (newsletter.From.HasText())
                            {
                                message.From = new MailAddress(newsletter.From, newsletter.DisplayFrom);
                            }
                            else
                            {
                                message.From = smtpConfig.DefaultFrom.ToMailAddress();
                            }

                            message.To.Add(conf.OverrideEmailAddress.DefaultText(s.Email.Email));

                            message.Subject = ((EmailTemplateParser.BlockNode)newsletter.SubjectParsedNode).Print(
                                new EmailTemplateParameters(null, null, dicTokenColumn, s.Rows)
                            {
                                IsHtml = false,
                            });

                            message.Body = ((EmailTemplateParser.BlockNode)newsletter.TextParsedNode).Print(
                                new EmailTemplateParameters(null, null, dicTokenColumn, s.Rows)
                            {
                                IsHtml = true,
                            });

                            message.IsBodyHtml = true;

                            client.Send(message);
                        }
                        catch (Exception ex)
                        {
                            s.Exception = ex;
                        }
                    });
                }

                var failed = group.Extract(sl => sl.Exception != null);
                foreach (var f in failed)
                {
                    new ProcessExceptionLineEntity
                    {
                        Exception = f.Exception.LogException().ToLite(),
                        Line      = f.NewsletterDelivery,
                        Process   = executingProcess.CurrentProcess.ToLite(),
                    }.Save();
                }


                var sent = group.Select(sl => sl.NewsletterDelivery).ToList();
                if (sent.Any())
                {
                    Database.Query <NewsletterDeliveryEntity>()
                    .Where(nd => sent.Contains(nd.ToLite()))
                    .UnsafeUpdate()
                    .Set(nd => nd.Sent, nd => true)
                    .Set(nd => nd.SendDate, nd => TimeZoneManager.Now.TrimToSeconds())
                    .Execute();
                }

                executingProcess.ProgressChanged(processed, lines.Count);
            }

            newsletter.State = NewsletterState.Sent;

            using (OperationLogic.AllowSave <NewsletterEntity>())
                newsletter.Save();
        }