Пример #1
0
        public static async Task SendNewCourseParticipantNotificationsAsync(IEnumerable <CourseParticipant> courseParticipants, MedSimDbContext repo, IPrincipal principal)
        {
            //logic:
            //get all courses hapening after now where the currentUser is not an organiser, and group by each organiser
            var currentUser = repo.Users.Include("Department").Include("ProfessionalRole").Single(u => u.UserName == principal.Identity.Name);
            var courseIds   = courseParticipants.ToHashSet(cp => cp.CourseId);
            var organisers  = repo.CourseParticipants.Include("Course.CourseFormat.CourseType")
                              .Include("Participant.Department.Institution")
                              .Include("Course.Department.Institution.Culture")
                              .Where(cp => courseIds.Contains(cp.CourseId) && cp.IsOrganiser && !cp.Course.CourseParticipants.Any(ap => ap.IsOrganiser && ap.ParticipantId == currentUser.Id))
                              .ToLookup(cp => cp.Participant);

            using (var client = new ParallelSmtpEmails())
            {
                foreach (var o in organisers)
                {
                    var n = new MultiCourseInviteResonse
                    {
                        Courses          = o.Select(cp => cp.Course),
                        PersonResponding = currentUser
                    };
                    var mail = new MailMessage();
                    mail.To.AddParticipants(o.Key);
                    mail.CreateHtmlBody(n);
                    client.Send(mail);
                }
                await client.SendingComplete();
            }
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="course"></param>
        /// <returns>a lookup true = successfully emailed, false = email failed</returns>
        public static async Task <EmailResult <CourseParticipant> > SendCourseEmail(Course course, ApplicationUserManager userManager, DateTime?originalDate = null)
        {
            var map     = ((Expression <Func <CourseParticipant, CourseParticipantDto> >) new CourseParticipantMaps().MapToDto).Compile();
            var faculty = course.CourseParticipants.Where(cp => map(cp).IsEmailed == originalDate.HasValue)
                          .ToLookup(cp => cp.IsFaculty);
            var    attachments          = new List <Attachment>();
            string timetableName        = CreateDocxTimetable.TimetableName(course);
            var    participantTimetable = CreateDocxTimetable.CreateTimetableDocx(course, WebApiConfig.DefaultTimetableTemplatePath, false);

            if (course.CourseFormat.CourseType.SendCandidateTimetable)
            {
                attachments.Add(new Attachment(Stream.Synchronized(participantTimetable), OpenXmlDocxExtensions.DocxMimeType)
                {
                    Name = timetableName
                });
            }

            attachments.AddRange(GetInviteReadings(course));

            var success = new ConcurrentBag <CourseParticipant>();
            var fail    = new ConcurrentBag <CourseParticipant>();

            using (var parallelEmails = new ParallelSmtpEmails(disposeMsgOnComplete: false))
            {
                List <MailMessage> messages = new List <MailMessage>(course.CourseParticipants.Count);
                var sendMail = new Func <CourseParticipant, Task>(async cp =>
                {
                    var mail = new MailMessage();
                    messages.Add(mail);
                    mail.To.AddParticipants(cp.Participant);
                    string token = await userManager.GenerateUserTokenAsync(InvitePurpose(cp.CourseId), cp.ParticipantId);

                    var confirmEmail = new CourseInvite {
                        CourseParticipant = cp, OldStart = originalDate, Token = token
                    };
                    mail.CreateHtmlBody(confirmEmail);
                    foreach (var a in attachments)
                    {
                        //a.ContentStream.Position = 0;
                        mail.Attachments.Add(a);
                    }
                    parallelEmails.Send(mail, s =>
                    {
                        if (s == null)
                        {
                            success.Add(cp);
                        }
                        else
                        {
                            fail.Add(cp);
                        }
                    });
                });

                foreach (var f in faculty[false])
                {
                    await sendMail(f);
                }

                MemoryStream facultyTimetable = null;
                if (faculty[true].Any())
                {
                    attachments      = new List <Attachment>();
                    facultyTimetable = CreateDocxTimetable.CreateTimetableDocx(course, WebApiConfig.DefaultTimetableTemplatePath, true);
                    attachments.Add(new Attachment(Stream.Synchronized(facultyTimetable), OpenXmlDocxExtensions.DocxMimeType)
                    {
                        Name = timetableName
                    });

                    attachments.AddRange(GetFilePaths(course)
                                         .Select(fp => new Attachment(Stream.Synchronized(fp.Value.ToStream()), System.Net.Mime.MediaTypeNames.Application.Zip)
                    {
                        Name = fp.Key
                    }));
                    foreach (var f in faculty[true])
                    {
                        await sendMail(f);
                    }
                }
                await parallelEmails.SendingComplete();

                messages.ForEach(m => m.Dispose());
                participantTimetable.Dispose();
                facultyTimetable?.Dispose();
            }
            return(new EmailResult <CourseParticipant> {
                SuccessRecipients = success.ToArray(),
                FailRecipients = fail.ToArray()
            });
        }
Пример #3
0
        public static async Task <EmailResult <CourseFacultyInvite> > SendMultiInvites(ICollection <Guid> courseIds, ICollection <Guid> participantIds, IPrincipal currentPrincipal, MedSimDbContext repo)
        {
            var existing = await repo.CourseFacultyInvites.Where(cfi => courseIds.Contains(cfi.CourseId) && participantIds.Contains(cfi.ParticipantId))
                           .ToHashSetAsync(cfi => Tuple.Create(cfi.CourseId, cfi.ParticipantId));

            existing.UnionWith((await repo.CourseParticipants
                                .Where(cp => courseIds.Contains(cp.CourseId) && participantIds.Contains(cp.ParticipantId)).ToListAsync())
                               .Select(cfi => Tuple.Create(cfi.CourseId, cfi.ParticipantId)));
            var allInvites = new List <CourseFacultyInvite>(courseIds.Count * participantIds.Count - existing.Count);

            foreach (var c in courseIds)
            {
                foreach (var p in participantIds)
                {
                    if (!existing.Contains(Tuple.Create(c, p)))
                    {
                        allInvites.Add(new CourseFacultyInvite {
                            CourseId = c, ParticipantId = p
                        });
                    }
                }
            }
            var success = new ConcurrentBag <CourseFacultyInvite>();
            var fail    = new ConcurrentBag <CourseFacultyInvite>();

            var allCourseIds = allInvites.ToHashSet(i => i.CourseId);
            var courses      = await repo.Courses.Include("CourseFormat.CourseType").Where(c => allCourseIds.Contains(c.Id)).ToDictionaryAsync(u => u.Id);

            var allInvitees   = allInvites.ToLookup(i => i.ParticipantId);
            var allInviteeIds = allInvitees.Select(i => i.Key);
            var userRepo      = (DbSet <Participant>)repo.Users;
            var users         = await userRepo.Include("Department.Institution.Culture").Where(p => allInviteeIds.Contains(p.Id)).ToDictionaryAsync(u => u.Id);

            var currentUser = await userRepo.Include("Department").Include("ProfessionalRole")
                              .SingleAsync(u => u.UserName == currentPrincipal.Identity.Name);

            using (var parallelEmails = new ParallelSmtpEmails())
            {
                foreach (var g in allInvitees)
                {
                    var mail = new MailMessage();

                    var recipient = users[g.Key];
                    mail.To.AddParticipants(recipient);
                    var requestEmail = new MultiCourseInvite
                    {
                        PersonRequesting = currentUser,
                        Courses          = g.Select(c => courses[c.CourseId]),
                        Recipient        = recipient
                    };
                    mail.CreateHtmlBody(requestEmail);
                    parallelEmails.Send(mail, s => {
                        if (s == null)
                        {
                            foreach (var ci in g)
                            {
                                success.Add(ci);
                            }
                        }
                        else
                        {
                            foreach (var ci in g)
                            {
                                fail.Add(ci);
                            }
                        }
                    });
                }
                await parallelEmails.SendingComplete();
            }
            return(new EmailResult <CourseFacultyInvite>
            {
                SuccessRecipients = success.ToArray(),
                FailRecipients = fail.ToArray()
            });
        }