2 using System.Collections.Generic;
3 using System.Configuration;
7 using System.Text.RegularExpressions;
11 using CPE.App.Web.Code;
12 using CPE.App.Web.Connect;
13 using CPE.App.Web.Helpers;
14 using CPE.App.Web.Models;
16 namespace CPE.App.Web.Controllers {
17 public class IndexController : BaseController {
18 public enum MeetingType {
23 private bool IsLocal() {
24 var address = Request.UserHostAddress;
25 if (address.StartsWith("192.") || address.StartsWith("10.211") || address == "::1")
32 public ActionResult Index(int? year) {
33 if(Request.Cookies["allowed"] == null && !IsLocal())
34 return Redirect("http://www.cpeonline.com/webcasts");
35 string systemPassword = ConfigurationManager.AppSettings["password"];
36 if(Request.Cookies["allowed"] != null && (Request.Cookies["allowed"].Value != systemPassword))
37 return Redirect("http://www.cpeonline.com/webcasts");
38 DateTime now = DateTime.UtcNow;
41 year = DateTime.Now.Year;
44 List<MeetingSessionsDataResult> meetingSessions = Database.MeetingSessionsData()
45 .Where(msd => msd.EndDate.HasValue && msd.EndDate <= now && (msd.StartDate >= new DateTime(year.Value, 1, 1) && msd.StartDate < new DateTime(year.Value + 1, 1, 1)))
46 .OrderByDescending(msd => msd.StartDate)
48 return View(meetingSessions);
52 public ActionResult SessionDetails(int meetingSessionKey) {
53 Extensions.LogServiceCall("[IndexController][SessionDetails]", string.Format("Beginning: meetingSessionKey = {0}", meetingSessionKey));
55 var meetingSession = Database.MeetingSessions.Single(ms => ms.MeetingSessionKey == meetingSessionKey);
56 var result = new AdobeSessionViewModel {
57 MeetingSession = meetingSession,
58 ParticipantSessionsDataResult = Database.ParticipantSessionsData(meetingSessionKey)
60 GetSessionReportResult = Database.GetSessionReport(meetingSessionKey)
62 WebcastPurchaseDataResult = Database.WebcastPurchaseData(meetingSession.SCO_ID, meetingSessionKey)
63 //.Where(w => w.Sco == meetingSession.SCO_ID && w.mDate.DayOfYear >= meetingSession.StartDate.DayOfYear)
66 //if (result.ParticipantSessionsDataResult.Count == 0) {
67 adobe.GetAdobeTransactions(meetingSession, Database);
68 Database.SubmitChanges();
70 result = new AdobeSessionViewModel {
71 MeetingSession = meetingSession,
72 ParticipantSessionsDataResult = Database.ParticipantSessionsData(meetingSessionKey)
74 GetSessionReportResult = Database.GetSessionReport(meetingSessionKey)
76 WebcastPurchaseDataResult = Database.WebcastPurchaseData(meetingSession.SCO_ID, meetingSessionKey)
84 public ActionResult RetrieveSession(int meetingSessionKey) {
85 Extensions.LogServiceCall("[IndexController][RetrieveSession]", string.Format("Beginning: meetingSessionKey = {0}", meetingSessionKey));
87 var meetingSession = Database.MeetingSessions.Single(ms => ms.MeetingSessionKey == meetingSessionKey);
88 if(Database.ParticipantSessionsData(meetingSessionKey)
91 adobe.GetAdobeTransactions(meetingSession, Database);
92 Database.SubmitChanges();
95 return RedirectToAction("SessionDetails", new {meetingSessionKey});
100 public ActionResult TestElucidat()
102 var baseUrl = "https://api-launchpad.elucidat.com/";
103 var urlFull = "health/ping";
104 Extensions.LogServiceCall("[IndexController][TestElucidat]", $"Beginning: {baseUrl}{urlFull}");
106 ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
107 ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls;
108 ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls11;
110 ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
112 var client = new WebClient { BaseAddress = baseUrl };
113 client.Headers.Clear();
114 client.Headers["Accept"] = "application/json";
115 var response = client.DownloadString(urlFull);
116 Extensions.LogServiceCall("[IndexController][TestElucidat]", $"Response: {response}");
119 return Content(response);
123 public ActionResult Login(string meetingUrl, string d = null, string c = null) {
124 meetingUrl = meetingUrl?.Trim();
129 Extensions.LogServiceCall("[IndexController][Login|Get]", string.Format("meetingUrl = {0} d (PurchaseDate) = {1} c (TicketFromUrl) = {2}", meetingUrl, d, c));
131 //Webcast and Rebroadcast access test course
132 if(meetingUrl.ToLower() == "test_room") {
133 var baseUrl = ConfigurationManager.AppSettings["Connect.Url"];
134 var testUrl = ConfigurationManager.AppSettings["Connect.AccessTestMeetingUrl"];
135 var accessTestUrl = baseUrl + '/' + testUrl;
136 return Redirect(accessTestUrl);
138 var meetingType = meetingUrl.Contains('-') ? MeetingType.Elucidat : MeetingType.Adobe;
140 if(meetingType == MeetingType.Elucidat) {
141 var releaseCode = meetingUrl.Substring(meetingUrl.IndexOf('-') + 1);
142 Extensions.LogServiceCall("[IndexController][Login|Get]", string.Format("meetingUrl = {0} releaseCode = {1}", meetingUrl, releaseCode));
144 ReleaseModel release = ElucidatMeetingConnection.GetReleaseDetails(releaseCode);
145 string projectName = null;
146 if(release != null && release.Project != null) {
147 projectName = release.Project.Name;
149 return View("elucidatlogin", new ElucidatCourseView {Name = projectName, Url = meetingUrl, PurchaseDate = d, TicketFromUrl = c, Message = null});
151 //if (ConfigurationManager.AppSettings["CPE.AdobeTicketingOn"].ToLower() == "true")
153 // //The flag is unnecessary now since we're keeping magic passcode access available. Non-ticketed link is now magicTicket
157 XmlDocument meeting = AdobeMeetingConnection.getAdobeMeeting(meetingUrl);
158 if(meeting != null) {
159 if(meeting.SelectSingleNode("//sco")
160 .Attributes["icon"].Value != "archive") {
161 return View("login", new AdobeMeetingView {
162 Name = meeting.SelectSingleNode("//sco/name")
164 HasPassCode = meeting.SelectSingleNode("//meeting-passcode") != null,
174 public ActionResult Login(string meetingUrl, string firstname, string lastname, string email, string passcode,
175 string courseName, string ticket = null, string ticketFromUrl = null, string purchaseDate = null,
176 string message = null) {
177 meetingUrl = meetingUrl?.Trim();
178 firstname = firstname?.Trim();
179 lastname = lastname?.Trim();
180 email = email?.Trim();
181 passcode = passcode?.Trim();
182 courseName = courseName?.Trim();
183 ticket = ticket?.Trim();
184 ticketFromUrl = ticketFromUrl?.Trim();
185 purchaseDate = purchaseDate?.Trim();
186 message = message?.Trim();
188 Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = {0} meetingUrl = {1} ticket = {2} ticketFromUrl = {3} purchaseDate = {4} firstname = {5} lastname = {6} passcode = {7} courseName = {8}", email, meetingUrl, ticket, ticketFromUrl, purchaseDate, firstname, lastname, passcode, courseName));
190 var magicTicketLogin = string.IsNullOrEmpty(ticketFromUrl);
191 var meetingType = meetingUrl.Contains('-') ? MeetingType.Elucidat : MeetingType.Adobe;
193 if(meetingType.Equals(MeetingType.Elucidat)) {
194 var releaseCode = meetingUrl.Substring(meetingUrl.IndexOf('-') + 1);
196 if(!ticket.Equals(ticketFromUrl) ||
197 !VerifyAccess.VerifyTicket(ticket, meetingUrl, firstname, lastname, email, purchaseDate)) {
198 return View("elucidatlogin", new ElucidatCourseView {
201 PurchaseDate = purchaseDate,
202 TicketFromUrl = ticketFromUrl,
204 "Invalid Login. Please re-enter your information. This information MUST match the information in the email you received with your passcode. If you continue to have trouble, please contact Customer Service at 1-800-544-1114 or email us at sswebcast@cpeincmail.com"
209 PurchasedCourse course =
210 Database.PurchasedCourses.SingleOrDefault(pc => pc.Ticket == ticket && pc.ContentUrl == meetingUrl);
213 //no purchase record yet, look for release details in database
214 CourseDetail release = Database.CourseDetails.SingleOrDefault(r => r.ReleaseCode == releaseCode);
215 if(release == null) {
216 //course isn't in db yet, get details form api
217 ReleaseModel releaseCourse = ElucidatMeetingConnection.GetReleaseDetails(releaseCode);
218 var done = ReleaseHelper.GetReleaseDescriptionDetails(releaseCourse);
220 release = Database.CourseDetails.SingleOrDefault(cd => cd.ReleaseCode == releaseCode);
223 string formattedPdate = purchaseDate.Substring(0, 4) + '-' + purchaseDate.Substring(4, 2) + '-' +
224 purchaseDate.Substring(6, 2);
225 DateTime pDate = Convert.ToDateTime(formattedPdate);
226 course = new PurchasedCourse {
227 ContentUrl = meetingUrl,
228 CourseName = release.Name,
229 FirstName = firstname,
233 PurchaseDate = pDate,
234 Presenter = release.Presenter,
236 Credits = release.Credits,
237 CertificateDate = null,
239 isManualCertificate = false
241 Database.PurchasedCourses.InsertOnSubmit(course);
244 Database.SubmitChanges();
246 //verify access (PurchaseDate<1yrold) and access not revoked
247 if(!VerifyAccess.AccessBlocked(course) && VerifyAccess.IsValid(course)) {
248 string courseUrl = ElucidatMeetingConnection.GetLaunchLink(releaseCode, firstname, lastname, email);
250 Regex linkParser = new Regex(@"\b(?:https?://)\S+\b",
251 RegexOptions.Compiled | RegexOptions.IgnoreCase);
252 string rawString = courseUrl;
253 string goodUrl = linkParser.Match(rawString)
256 return Redirect(goodUrl);
259 //Access is expired or Revoked
260 return View("elucidatlogin", new ElucidatCourseView {
263 PurchaseDate = purchaseDate,
264 TicketFromUrl = ticketFromUrl,
266 "Access to this course is no longer available. Please contact Customer Service at 1-800-544-1114 or email us at sswebcast@cpeincmail.com"
270 if((ConfigurationManager.AppSettings["CPE.AdobeTicketingOn"].ToLower() == "true") & !magicTicketLogin) {
271 if(passcode == null) {
272 passcode = (DateTime.UtcNow.ToString("MMM") + DateTime.UtcNow.Day.ToString("00")).ToLower();
274 if(!ticketFromUrl.Equals(ticket)) {
275 return RedirectToAction("Login");
277 if(!VerifyAccess.VerifyTicket(ticket, meetingUrl, firstname, lastname, email, purchaseDate)) {
278 return RedirectToAction("Login");
281 //if valid continue on to existing way of doing things
284 string connectUrl = ConfigurationManager.AppSettings["Connect.Url"];
285 int accountId = int.Parse(ConfigurationManager.AppSettings["Connect.AccountId"]);
286 string password = Guid.NewGuid()
291 Session admin = AdobeMeetingConnection.GetAdobeAdminSession();
292 var request = new Request(admin, "principal-list");
293 request.Parameters.Add("filter-type", "guest");
294 request.Parameters.Add("filter-type", "user");
295 request.Parameters.Add("filter-login", email);
296 if(request.Execute() && request.Status == Status.OK) {
297 Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = [{0}] request.XmlResults.InnerXml = {1}", email, request.XmlResults.InnerXml));
300 if(request.XmlResults.SelectSingleNode("//principal") == null) {
301 principalId = Connect.Login.CreateGuest(admin, email, password, email, firstname, lastname);
303 principalId = int.Parse(request.XmlResults.SelectSingleNode("//principal")
304 .Attributes["principal-id"].Value);
305 email = request.XmlResults.SelectSingleNode("//principal/login")
307 if(request.XmlResults.SelectSingleNode("//principal")
308 .Attributes["type"].Value == "user")
309 return RedirectToAction("Login");
312 return RedirectToAction("Login");
315 Connect.Login.ResetPassword(admin, principalId, password);
316 Session session = Connect.Login.UserLogin(email, password, connectUrl, accountId);
318 var meetingView = new AdobeMeetingView {
319 Name = AdobeMeetingConnection.getAdobeMeetingName(meetingUrl),
320 PrincipalId = principalId,
322 string.Format("{0}/{1}?session={2}&launcher=false", connectUrl, meetingUrl,
323 session.SessionKey) + (passcode == null
325 : "&meeting-passcode=" + passcode)
329 Participant participant = Database.Participants.SingleOrDefault(p => p.Principal_ID == principalId);
330 if(participant == null) {
331 participant = new Participant {
332 Principal_ID = principalId,
333 FirstName = firstname,
337 Database.Participants.InsertOnSubmit(participant);
340 Database.SubmitChanges();
342 var certificateId = 0;
343 int scoId = AdobeMeetingConnection.getAdobeMeetingSco(meetingUrl);
345 if(!magicTicketLogin) {
346 string formattedPdate = purchaseDate.Substring(0, 4) + '-' +
347 purchaseDate.Substring(4, 2) +
348 '-' + purchaseDate.Substring(6, 2);
349 DateTime pDate = Convert.ToDateTime(formattedPdate);
351 ParticipantPurchase purchase =
352 Database.ParticipantPurchases.SingleOrDefault(
354 p.PrincipalID == principalId & p.Ticket == ticketFromUrl &
355 p.MeetingSco == scoId);
356 if(purchase == null) {
357 purchase = new ParticipantPurchase {
358 FirstName = firstname,
361 PrincipalID = principalId,
362 MeetingName = meetingView.Name,
363 MeetingDate = DateTime.UtcNow,
365 Ticket = ticketFromUrl,
366 PurchaseDate = pDate,
367 EarnedCertificate = false,
370 Database.ParticipantPurchases.InsertOnSubmit(purchase);
372 Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = {0} scoId = {1} principalId = {2} MeetingDate = {3}", email, scoId, principalId, purchase.MeetingDate));
375 Database.SubmitChanges();
376 certificateId = purchase.Purchase_ID;
378 meetingView.CertificateId = certificateId;
379 meetingView.ScoId = scoId;
381 Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = {0} scoId = {1} certificateId = {2} principalId = {3}", email, scoId, certificateId, principalId));
383 var idCookie = new HttpCookie("id") {
384 Value = principalId.ToString(),
385 Expires = DateTime.UtcNow.AddDays(1)
387 Response.Cookies.Add(idCookie);
390 request = new Request(admin, "principal-update");
391 request.Parameters.Add("first-name", firstname);
392 request.Parameters.Add("last-name", lastname);
393 request.Parameters.Add("principal-id", principalId.ToString());
396 return View("meeting", meetingView);
398 return RedirectToAction("Login");
402 public ActionResult Admin() {
406 public ActionResult Email() {
407 var email = new MailMessage {
409 "tallen@intesolv.com"
411 Subject = "[CPE] Email Test",
412 Body = "Email test has been received.",
413 From = new MailAddress("support@intesolv.com")
415 var server = new SmtpClient("localhost");
418 return Redirect("/");
422 public ActionResult Admin(string login, string passcode) {
423 login = login?.Trim();
424 passcode = passcode?.Trim();
426 string systemPassword = ConfigurationManager.AppSettings["password"];
427 if(login == ConfigurationManager.AppSettings["login"] & passcode == systemPassword) {
428 var reportingCookie = new HttpCookie("allowed") {
429 Value = systemPassword,
430 Expires = DateTime.UtcNow.AddDays(1)
432 Response.Cookies.Add(reportingCookie);
434 return Redirect("/");
438 public ActionResult CourseDetails(string releaseCode) {
439 releaseCode = releaseCode?.Trim();
441 var course = Database.CourseDetails.Single(cd => cd.ReleaseCode == releaseCode);
442 var result = new ElucidatCourseViewModel {
443 CourseDetail = course,
444 PurchasedCoursesDataResult = Database.PurchasedCoursesData(releaseCode)
445 .OrderByDescending(pc => pc.PurchaseDate)
453 public ActionResult Elucidat() {
454 if(Request.Cookies["allowed"] == null && !IsLocal())
455 return Redirect("http://www.cpeonline.com/webcasts");
456 string systemPassword = ConfigurationManager.AppSettings["password"];
457 if(Request.Cookies["allowed"] != null && (Request.Cookies["allowed"].Value != systemPassword))
458 return Redirect("http://www.cpeonline.com/webcasts");
459 DateTime now = DateTime.UtcNow;
461 List<CourseListingsDataResult> courseListings = Database.CourseListingsData()
462 .Where(cl => cl.CreatedDate != null)
463 .OrderBy(cl => cl.Name)
465 return View(courseListings);
469 public ActionResult Wufoo(int id) {
470 //https://cpeonline.wufoo.com/forms/cpe-webcast-evaluation/def/Field1=Jason&Field2=Wigginton&Field3-1=7&Field3-2=2&Field3=2012&Field4=1234&Field5=J.%20McIntosh&Field6=ConnectPro&Field7=Test101&Field8=Test%20topic
471 ParticipantTracking pt = Database.ParticipantTrackings.OrderByDescending(p => p.StartDate)
472 .FirstOrDefault(p => p.Principal_ID == id);
473 string url = ConfigurationManager.AppSettings["Wufoo.Survey1.1"];
475 Extensions.LogServiceCall("[IndexController][Wufoo]", string.Format("id = {0} url = {1}", id, url));
476 return Redirect(url);
479 MeetingDetail d = pt.MeetingParticipantSession.MeetingSession.Meeting.MeetingDetail;
480 DateTime date = Extensions.GetLocalDateTime(DateTime.UtcNow);
481 url += string.Format(ConfigurationManager.AppSettings["Wufoo.Survey1.2"], pt.Participant.FirstName, pt.Participant.LastName, date.Month.ToString("00"), date.Day.ToString("00"), date.Year, d.TopicID, d.TopicName, d.Instructor, d.Location, d.CourseCode);
482 Extensions.LogServiceCall("[IndexController][Wufoo]", string.Format("id = {0} url = {1}", id, url));
483 return Redirect(url);
486 public ActionResult Survey() {
488 string url = ConfigurationManager.AppSettings["Wufoo.Survey1.1"];
489 string cookie = Request.Cookies["id"] == null
491 : Request.Cookies["id"].Value;
492 int.TryParse(cookie, out id);
494 return Redirect(url);
496 Extensions.LogServiceCall("[IndexController][Survey]", string.Format("id = {0}", id));
497 ParticipantTracking pt = Database.ParticipantTrackings.OrderByDescending(p => p.StartDate)
498 .FirstOrDefault(p => p.Principal_ID == id);
500 return Redirect(url);
502 MeetingDetail d = pt.MeetingParticipantSession.MeetingSession.Meeting.MeetingDetail;
503 DateTime date = Extensions.GetLocalDateTime(DateTime.UtcNow);
504 url += string.Format(ConfigurationManager.AppSettings["Wufoo.Survey1.2"], pt.Participant.FirstName, pt.Participant.LastName, date.Month.ToString("00"), date.Day.ToString("00"), date.Year, d.TopicID, d.TopicName, d.Instructor, d.Location, d.CourseCode);
505 return Redirect(url);
509 public ActionResult AllowReporting(Guid? id) {
510 //if (id.HasValue && id == Guid.Parse("")) {
511 // var reportingCookie = new HttpCookie("reporting") {Value = "1", Expires = DateTime.MaxValue};
512 // Response.Cookies.Add(reportingCookie);
513 // return Redirect("/");
515 //return Redirect("http://www.cpeonline.com/webcasts");
516 return RedirectToAction("Admin");
520 public ActionResult GetTicket(string courseUrl) {
521 courseUrl = courseUrl?.Trim();
523 TicketModel ticketInfo = new TicketModel {
524 CourseUrl = courseUrl
526 //return the view as a partial view that opens in a pretty jquery ui form (dialog) within the page, not a new page
527 return PartialView(ticketInfo);
531 public string GetTicket(string firstname, string lastname, string email, string contenturl) {
532 //NOT IMPLEMENTED. possible solution to "magic ticket" request for ondemand course, since a global entry would not make sense
533 //generate hashed ticket link for a specific user for an ondemand course. This will bypass cpe's commerce site and allow cpe customer service to generate an access link
535 firstname = firstname?.Trim();
536 lastname = lastname?.Trim();
537 email = email?.Trim();
538 contenturl = contenturl?.Trim();
540 string purchasedate = DateTime.Now.ToString("yyyyMMdd");
541 var ticket = VerifyAccess.generateTicket(contenturl, firstname, lastname, email, purchasedate);
543 var link = "http://cpeonlineselfstudywebcasts.com/" + contenturl + "?d=" + purchasedate + "&c=" + ticket;
547 // GET: CertificateReport
549 public ActionResult CertificateReport() {
550 List<CertficateDataResult> earnedCertificates = Database.CertficateData()
551 .OrderBy(ec => ec.Course)
553 return View(earnedCertificates);
556 public ActionResult WebcastCertificateReport() {
557 List<WebcastCertficateDataResult> earnedCertificates = Database.WebcastCertficateData()
558 .OrderBy(ec => ec.MeetingName)
560 return View(earnedCertificates);
563 //public string SendCert(int meeting_sco, int certificate_id, int principal_id)
565 // //TODO (webcast) make outcome dictionary to return pass, fail, ineligible, or wonky:contact cust serv
566 // string _fail = "fail";
567 // if (certificate_id > 0)
569 // ParticipantPurchase purchase =
570 // Database.ParticipantPurchases.FirstOrDefault(p => p.Purchase_ID == certificate_id && p.PrincipalID == principal_id);
572 // if (purchase == null)
574 // //if the certificate_id is >0 then purchase would only be null because of record being deleted while user was in the meeting, or the principalID got mis-matched
575 // return _fail; // TODO probably return wonky, contact cust service message
578 // if (!purchase.EarnedCertificate)
580 // var meeting = Database.MeetingSessions.FirstOrDefault(
582 // m.Recording == false && m.SCO_ID == meeting_sco &&
583 // m.StartDate.DayOfYear == DateTime.UtcNow.DayOfYear);
584 // if (meeting == null)
586 // return _fail;//TODO return wonky
589 // int meetingSessionKey = meeting.MeetingSessionKey;
591 // MeetingParticipantSession meetingParticipantSession =
592 // Database.MeetingParticipantSessions.FirstOrDefault(
593 // m => m.MeetingSessionKey == meetingSessionKey && m.ParticipantKey == principal_id);
594 // if (meetingParticipantSession == null)
596 // return _fail;//TODO return wonky
599 // List<ParticipantSessionsDataResult> participantSessionsDataResult =
600 // Database.ParticipantSessionsData(meetingSessionKey)
603 // var participantSessionsData =
604 // participantSessionsDataResult.OrderBy(p => p.MeetingParticipantSessionKey)
607 // p.MeetingParticipantSessionKey ==
608 // meetingParticipantSession.MeetingParticipantSessionKey);
610 // if (participantSessionsData == null)
612 // return _fail;//TODO is this a return wonky? it means they weren't tracked
615 // MeetingSessionsDataResult meetingSession = Database.MeetingSessionsData().FirstOrDefault(m => m.MeetingSessionKey == meetingSessionKey);
616 // if (meetingSession == null)
618 // return _fail;//TODO return wonky
621 // var courseLength = meetingSession.ActualSessionTime.GetValueOrDefault(); //in minutes
622 // double courseCredits = courseLength / 50.0; //1 credit per 50 minutes
623 // List<double> maxCourseCredits = ConfigurationManager.AppSettings["MaxCourseCreditList"].Split(';').Select(s => double.Parse(s)).ToList(); //max credits cut list
624 // int mx = maxCourseCredits.BinarySearch(courseCredits); //find appropriate max for this course
625 // double maxCredits = maxCourseCredits[mx >= 0 ? mx : ~mx - 1];//...by rounding down
626 // double realCredits = participantSessionsData.SessionCredit == null ? 0 : (double)participantSessionsData.SessionCredit.Value; //users credits per adobe
627 // purchase.Credits = Math.Min(maxCredits, realCredits); //user awarded no more than max possible credits for the course
629 // MeetingDetail meetingDetail =
630 // Database.MeetingDetails.FirstOrDefault(m => m.MeetingKey == purchase.MeetingSco);
632 // purchase.Presenter = meetingDetail == null ? "" : meetingDetail.Instructor;
634 // double percentComplete = (participantSessionsData.SessionEngagementCount.GetValueOrDefault() == 0 ?
635 // 1 : (participantSessionsData.SessionHeartbeatCount.GetValueOrDefault() / participantSessionsData.SessionEngagementCount.Value));
637 // if (percentComplete >= .75) //threshold for earning a certificate is 75% response rate
639 // purchase.EarnedCertificate = true;
642 // Database.SubmitChanges();
644 // if (purchase.EarnedCertificate)
646 // //TODO with return Pass dictionary value as string.format with replace of certUrl
647 // //string certUrl = AdobeCertificateHelper.SendWebcastCert(purchase);
648 // //format the outcome.pass.value message with certUrl replace
649 // //return outcome.pass with its value
650 // return AdobeCertificateHelper.SendWebcastCert(purchase);
652 // //TODO return outcome.fail
653 // return AdobeCertificateHelper.SendFailNotice(purchase);
656 // return _fail;// TODO return ineligible.need to make AdobeCertificateHelper.SendIneligibleNotice(principalId)
659 //public participantResult ProcessParticipantResult(participantResult result, ParticipantPurchase purchase)
661 // if (purchase == null)
663 // result = participantResult.Ineligible;
667 // case participantResult.Ineligible:
668 // //Ineligible for auto-cert; not sending notice.
670 // case participantResult.Fail:
671 // AdobeCertificateHelper.SendFailNotice(purchase);
673 // case participantResult.Pass:
674 // AdobeCertificateHelper.SendWebcastCert(purchase);
675 // //Send Cert email;
677 // case participantResult.Wonky:
678 // //something went wrong: send email to contact cust service? send email to cpe? do nothing?
684 //public ActionResult BatchProcessParticipantResults(int msk)
686 // List<ParticipantSessionsDataResult> psdr = BaseController.Database.ParticipantSessionsData(msk).ToList();
687 // var meeting = BaseController.Database.MeetingSessions.FirstOrDefault(m => m.MeetingSessionKey == msk);
688 // if (meeting == null)
690 // return Content("Error retrieving meeting session details.");
692 // var scoId = meeting.SCO_ID;
694 // foreach (var p in psdr)
696 // ParticipantPurchase purchase = null;
697 // participantResult result = participantResult.Wonky;
698 // var mpsk = p.MeetingParticipantSessionKey;
699 // var meetingParticipantSession =
700 // BaseController.Database.MeetingParticipantSessions.FirstOrDefault(
701 // mps => mps.MeetingParticipantSessionKey == mpsk && mps.MeetingSessionKey == msk);
703 // if (meetingParticipantSession != null)
705 // var principalId = meetingParticipantSession.ParticipantKey;
707 // purchase = BaseController.Database.ParticipantPurchases.FirstOrDefault(pp => pp.PrincipalID == principalId && pp.MeetingSco == scoId);
708 // if (purchase == null)
710 // result = participantResult.Ineligible;
714 // MeetingSessionsDataResult meetingSession = Database.MeetingSessionsData().FirstOrDefault(m => m.MeetingSessionKey == msk);
715 // if (meetingSession != null)
717 // var courseLength = meetingSession.ActualSessionTime.GetValueOrDefault(); //in minutes
718 // double courseCredits = courseLength/50.0; //1 credit per 50 minutes
719 // List<double> maxCourseCredits =
720 // ConfigurationManager.AppSettings["MaxCourseCreditList"].Split(';')
721 // .Select(s => double.Parse(s))
722 // .ToList(); //max credits cut list
723 // int mx = maxCourseCredits.BinarySearch(courseCredits);
724 // //find appropriate max for this course
725 // double maxCredits = maxCourseCredits[mx >= 0 ? mx : ~mx - 1]; //...by rounding down
726 // double realCredits = p.SessionCredit == null
728 // : (double) p.SessionCredit.Value; //users credits
729 // purchase.Credits = Math.Min(maxCredits, realCredits);
730 // //user awarded no more than max possible credits for the course
732 // MeetingDetail meetingDetail =
733 // Database.MeetingDetails.FirstOrDefault(m => m.MeetingKey == purchase.MeetingSco);
735 // purchase.Presenter = meetingDetail == null ? "" : meetingDetail.Instructor;
737 // double percentComplete =
738 // (p.SessionEngagementCount.GetValueOrDefault() == 0
740 // : (p.SessionHeartbeatCount.GetValueOrDefault()/
741 // p.SessionEngagementCount.Value));
743 // if (percentComplete >= .75) //threshold for earning a certificate is 75% response rate
745 // purchase.EarnedCertificate = true;
746 // result = participantResult.Pass;
750 // result = participantResult.Fail;
753 // Database.SubmitChanges();
757 // ProcessParticipantResult(result, purchase);
759 // return Content("done");
762 public ActionResult Result(int principalid, int scoid) {
763 var resultView = new SessionResultViewModel();
764 participantResult result = participantResult.Wonky;
766 Extensions.LogServiceCall("[IndexController][Result]", string.Format("Beginning: principalid = {0} scoid = {1}", principalid, scoid));
768 Extensions.LogServiceCall("[IndexController][Result]", string.Format(
769 "principalid = {0} scoid = {1} DateTime.UtcNow.DayOfYear = {2} DateTime.Now.DayOfYear = {3}",
770 principalid, scoid, DateTime.UtcNow.DayOfYear, DateTime.Now.DayOfYear));
773 Database.MeetingSessions.FirstOrDefault(
774 m => m.SCO_ID == scoid && m.StartDate.DayOfYear == DateTime.UtcNow.DayOfYear);
775 if(meeting != null) {
776 int msk = meeting.MeetingSessionKey;
777 MeetingParticipantSession meetingParticipantSession =
778 Database.MeetingParticipantSessions.FirstOrDefault(
779 m => m.MeetingSessionKey == msk && m.ParticipantKey == principalid);
780 if(meetingParticipantSession != null) {
781 adobe.GetAdobeTransactions(meetingParticipantSession.MeetingSession, Database);
782 Database.SubmitChanges();
784 result = SessionEnd.ProcessEndOfMeetingSessionHeartbeatResultsForParticipant(Database, meetingParticipantSession);
786 case participantResult.Ineligible:
787 resultView.Message = Utilities.Result.RenderIneligibleResult(principalid);
789 case participantResult.Fail:
790 resultView.Message = Utilities.Result.RenderFailResult(principalid);
792 case participantResult.Pass:
793 resultView.Message = Utilities.Result.RenderPassResult(principalid);
795 case participantResult.Wonky:
796 resultView.Message = Utilities.Result.RenderWonkyResult();
800 Extensions.LogServiceCall("[IndexController][Result]", string.Format(
801 "meetingParticipantSession is null: principalid = {0} scoid= {1} msk = {2}",
802 principalid, scoid, msk));
805 Extensions.LogServiceCall("[IndexController][Result]", string.Format(
806 "meeting is null: principalid = {0} scoid= {1} DateTime.UtcNow.DayOfYear = {2} DateTime.Now.DayOfYear = {3}",
807 principalid, scoid, DateTime.UtcNow.DayOfYear, DateTime.Now.DayOfYear));
809 resultView.Result = (int) result;
810 return View("result", resultView);