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 "sophia@sophicsystems.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("/");
420 public ActionResult SendCerificateEmail(string email, string url, string key)
422 if (key != "q1w2e3") return Content("Bad key");
423 var course = Database.PurchasedCourses
424 .Where(c => c.Email == email && c.ContentUrl == url)
425 .OrderByDescending(c => c.CertificateDate).FirstOrDefault();
427 var done = SendEmailHelperWeb.SendCertificateEmail(course);
429 var s = url.Split('-');
430 var courseName = Database.CourseDetails
431 .FirstOrDefault(c => c.ReleaseCode == s[1])?.Name;
433 Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} cert sent email={1} courseName={2}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName);
435 return Content("Certificate send successfully");
439 public ActionResult Admin(string login, string passcode) {
440 login = login?.Trim();
441 passcode = passcode?.Trim();
443 string systemPassword = ConfigurationManager.AppSettings["password"];
444 if(login == ConfigurationManager.AppSettings["login"] & passcode == systemPassword) {
445 var reportingCookie = new HttpCookie("allowed") {
446 Value = systemPassword,
447 Expires = DateTime.UtcNow.AddDays(1)
449 Response.Cookies.Add(reportingCookie);
451 return Redirect("/");
455 public ActionResult CourseDetails(string releaseCode) {
456 releaseCode = releaseCode?.Trim();
458 var course = Database.CourseDetails.Single(cd => cd.ReleaseCode == releaseCode);
459 var result = new ElucidatCourseViewModel {
460 CourseDetail = course,
461 PurchasedCoursesDataResult = Database.PurchasedCoursesData(releaseCode)
462 .OrderByDescending(pc => pc.PurchaseDate)
470 public ActionResult Elucidat() {
471 if(Request.Cookies["allowed"] == null && !IsLocal())
472 return Redirect("http://www.cpeonline.com/webcasts");
473 string systemPassword = ConfigurationManager.AppSettings["password"];
474 if(Request.Cookies["allowed"] != null && (Request.Cookies["allowed"].Value != systemPassword))
475 return Redirect("http://www.cpeonline.com/webcasts");
476 DateTime now = DateTime.UtcNow;
478 List<CourseListingsDataResult> courseListings = Database.CourseListingsData()
479 .Where(cl => cl.CreatedDate != null)
480 .OrderBy(cl => cl.Name)
482 return View(courseListings);
486 public ActionResult Wufoo(int id) {
487 //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
488 ParticipantTracking pt = Database.ParticipantTrackings.OrderByDescending(p => p.StartDate)
489 .FirstOrDefault(p => p.Principal_ID == id);
490 string url = ConfigurationManager.AppSettings["Wufoo.Survey1.1"];
492 Extensions.LogServiceCall("[IndexController][Wufoo]", string.Format("id = {0} url = {1}", id, url));
493 return Redirect(url);
496 MeetingDetail d = pt.MeetingParticipantSession.MeetingSession.Meeting.MeetingDetail;
497 DateTime date = Extensions.GetLocalDateTime(DateTime.UtcNow);
498 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);
499 Extensions.LogServiceCall("[IndexController][Wufoo]", string.Format("id = {0} url = {1}", id, url));
500 return Redirect(url);
503 public ActionResult Survey() {
505 string url = ConfigurationManager.AppSettings["Wufoo.Survey1.1"];
506 string cookie = Request.Cookies["id"] == null
508 : Request.Cookies["id"].Value;
509 int.TryParse(cookie, out id);
511 return Redirect(url);
513 Extensions.LogServiceCall("[IndexController][Survey]", string.Format("id = {0}", id));
514 ParticipantTracking pt = Database.ParticipantTrackings.OrderByDescending(p => p.StartDate)
515 .FirstOrDefault(p => p.Principal_ID == id);
517 return Redirect(url);
519 MeetingDetail d = pt.MeetingParticipantSession.MeetingSession.Meeting.MeetingDetail;
520 DateTime date = Extensions.GetLocalDateTime(DateTime.UtcNow);
521 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);
522 return Redirect(url);
526 public ActionResult AllowReporting(Guid? id) {
527 //if (id.HasValue && id == Guid.Parse("")) {
528 // var reportingCookie = new HttpCookie("reporting") {Value = "1", Expires = DateTime.MaxValue};
529 // Response.Cookies.Add(reportingCookie);
530 // return Redirect("/");
532 //return Redirect("http://www.cpeonline.com/webcasts");
533 return RedirectToAction("Admin");
537 public ActionResult GetTicket(string courseUrl) {
538 courseUrl = courseUrl?.Trim();
540 TicketModel ticketInfo = new TicketModel {
541 CourseUrl = courseUrl
543 //return the view as a partial view that opens in a pretty jquery ui form (dialog) within the page, not a new page
544 return PartialView(ticketInfo);
548 public string GetTicket(string firstname, string lastname, string email, string contenturl) {
549 //NOT IMPLEMENTED. possible solution to "magic ticket" request for ondemand course, since a global entry would not make sense
550 //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
552 firstname = firstname?.Trim();
553 lastname = lastname?.Trim();
554 email = email?.Trim();
555 contenturl = contenturl?.Trim();
557 string purchasedate = DateTime.Now.ToString("yyyyMMdd");
558 var ticket = VerifyAccess.generateTicket(contenturl, firstname, lastname, email, purchasedate);
560 var link = "http://cpeonlineselfstudywebcasts.com/" + contenturl + "?d=" + purchasedate + "&c=" + ticket;
564 // GET: CertificateReport
566 public ActionResult CertificateReport() {
567 List<CertficateDataResult> earnedCertificates = Database.CertficateData()
568 .OrderBy(ec => ec.Course)
570 return View(earnedCertificates);
573 public ActionResult WebcastCertificateReport() {
574 List<WebcastCertficateDataResult> earnedCertificates = Database.WebcastCertficateData()
575 .OrderBy(ec => ec.MeetingName)
577 return View(earnedCertificates);
580 //public string SendCert(int meeting_sco, int certificate_id, int principal_id)
582 // //TODO (webcast) make outcome dictionary to return pass, fail, ineligible, or wonky:contact cust serv
583 // string _fail = "fail";
584 // if (certificate_id > 0)
586 // ParticipantPurchase purchase =
587 // Database.ParticipantPurchases.FirstOrDefault(p => p.Purchase_ID == certificate_id && p.PrincipalID == principal_id);
589 // if (purchase == null)
591 // //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
592 // return _fail; // TODO probably return wonky, contact cust service message
595 // if (!purchase.EarnedCertificate)
597 // var meeting = Database.MeetingSessions.FirstOrDefault(
599 // m.Recording == false && m.SCO_ID == meeting_sco &&
600 // m.StartDate.DayOfYear == DateTime.UtcNow.DayOfYear);
601 // if (meeting == null)
603 // return _fail;//TODO return wonky
606 // int meetingSessionKey = meeting.MeetingSessionKey;
608 // MeetingParticipantSession meetingParticipantSession =
609 // Database.MeetingParticipantSessions.FirstOrDefault(
610 // m => m.MeetingSessionKey == meetingSessionKey && m.ParticipantKey == principal_id);
611 // if (meetingParticipantSession == null)
613 // return _fail;//TODO return wonky
616 // List<ParticipantSessionsDataResult> participantSessionsDataResult =
617 // Database.ParticipantSessionsData(meetingSessionKey)
620 // var participantSessionsData =
621 // participantSessionsDataResult.OrderBy(p => p.MeetingParticipantSessionKey)
624 // p.MeetingParticipantSessionKey ==
625 // meetingParticipantSession.MeetingParticipantSessionKey);
627 // if (participantSessionsData == null)
629 // return _fail;//TODO is this a return wonky? it means they weren't tracked
632 // MeetingSessionsDataResult meetingSession = Database.MeetingSessionsData().FirstOrDefault(m => m.MeetingSessionKey == meetingSessionKey);
633 // if (meetingSession == null)
635 // return _fail;//TODO return wonky
638 // var courseLength = meetingSession.ActualSessionTime.GetValueOrDefault(); //in minutes
639 // double courseCredits = courseLength / 50.0; //1 credit per 50 minutes
640 // List<double> maxCourseCredits = ConfigurationManager.AppSettings["MaxCourseCreditList"].Split(';').Select(s => double.Parse(s)).ToList(); //max credits cut list
641 // int mx = maxCourseCredits.BinarySearch(courseCredits); //find appropriate max for this course
642 // double maxCredits = maxCourseCredits[mx >= 0 ? mx : ~mx - 1];//...by rounding down
643 // double realCredits = participantSessionsData.SessionCredit == null ? 0 : (double)participantSessionsData.SessionCredit.Value; //users credits per adobe
644 // purchase.Credits = Math.Min(maxCredits, realCredits); //user awarded no more than max possible credits for the course
646 // MeetingDetail meetingDetail =
647 // Database.MeetingDetails.FirstOrDefault(m => m.MeetingKey == purchase.MeetingSco);
649 // purchase.Presenter = meetingDetail == null ? "" : meetingDetail.Instructor;
651 // double percentComplete = (participantSessionsData.SessionEngagementCount.GetValueOrDefault() == 0 ?
652 // 1 : (participantSessionsData.SessionHeartbeatCount.GetValueOrDefault() / participantSessionsData.SessionEngagementCount.Value));
654 // if (percentComplete >= .75) //threshold for earning a certificate is 75% response rate
656 // purchase.EarnedCertificate = true;
659 // Database.SubmitChanges();
661 // if (purchase.EarnedCertificate)
663 // //TODO with return Pass dictionary value as string.format with replace of certUrl
664 // //string certUrl = AdobeCertificateHelper.SendWebcastCert(purchase);
665 // //format the outcome.pass.value message with certUrl replace
666 // //return outcome.pass with its value
667 // return AdobeCertificateHelper.SendWebcastCert(purchase);
669 // //TODO return outcome.fail
670 // return AdobeCertificateHelper.SendFailNotice(purchase);
673 // return _fail;// TODO return ineligible.need to make AdobeCertificateHelper.SendIneligibleNotice(principalId)
676 //public participantResult ProcessParticipantResult(participantResult result, ParticipantPurchase purchase)
678 // if (purchase == null)
680 // result = participantResult.Ineligible;
684 // case participantResult.Ineligible:
685 // //Ineligible for auto-cert; not sending notice.
687 // case participantResult.Fail:
688 // AdobeCertificateHelper.SendFailNotice(purchase);
690 // case participantResult.Pass:
691 // AdobeCertificateHelper.SendWebcastCert(purchase);
692 // //Send Cert email;
694 // case participantResult.Wonky:
695 // //something went wrong: send email to contact cust service? send email to cpe? do nothing?
701 //public ActionResult BatchProcessParticipantResults(int msk)
703 // List<ParticipantSessionsDataResult> psdr = BaseController.Database.ParticipantSessionsData(msk).ToList();
704 // var meeting = BaseController.Database.MeetingSessions.FirstOrDefault(m => m.MeetingSessionKey == msk);
705 // if (meeting == null)
707 // return Content("Error retrieving meeting session details.");
709 // var scoId = meeting.SCO_ID;
711 // foreach (var p in psdr)
713 // ParticipantPurchase purchase = null;
714 // participantResult result = participantResult.Wonky;
715 // var mpsk = p.MeetingParticipantSessionKey;
716 // var meetingParticipantSession =
717 // BaseController.Database.MeetingParticipantSessions.FirstOrDefault(
718 // mps => mps.MeetingParticipantSessionKey == mpsk && mps.MeetingSessionKey == msk);
720 // if (meetingParticipantSession != null)
722 // var principalId = meetingParticipantSession.ParticipantKey;
724 // purchase = BaseController.Database.ParticipantPurchases.FirstOrDefault(pp => pp.PrincipalID == principalId && pp.MeetingSco == scoId);
725 // if (purchase == null)
727 // result = participantResult.Ineligible;
731 // MeetingSessionsDataResult meetingSession = Database.MeetingSessionsData().FirstOrDefault(m => m.MeetingSessionKey == msk);
732 // if (meetingSession != null)
734 // var courseLength = meetingSession.ActualSessionTime.GetValueOrDefault(); //in minutes
735 // double courseCredits = courseLength/50.0; //1 credit per 50 minutes
736 // List<double> maxCourseCredits =
737 // ConfigurationManager.AppSettings["MaxCourseCreditList"].Split(';')
738 // .Select(s => double.Parse(s))
739 // .ToList(); //max credits cut list
740 // int mx = maxCourseCredits.BinarySearch(courseCredits);
741 // //find appropriate max for this course
742 // double maxCredits = maxCourseCredits[mx >= 0 ? mx : ~mx - 1]; //...by rounding down
743 // double realCredits = p.SessionCredit == null
745 // : (double) p.SessionCredit.Value; //users credits
746 // purchase.Credits = Math.Min(maxCredits, realCredits);
747 // //user awarded no more than max possible credits for the course
749 // MeetingDetail meetingDetail =
750 // Database.MeetingDetails.FirstOrDefault(m => m.MeetingKey == purchase.MeetingSco);
752 // purchase.Presenter = meetingDetail == null ? "" : meetingDetail.Instructor;
754 // double percentComplete =
755 // (p.SessionEngagementCount.GetValueOrDefault() == 0
757 // : (p.SessionHeartbeatCount.GetValueOrDefault()/
758 // p.SessionEngagementCount.Value));
760 // if (percentComplete >= .75) //threshold for earning a certificate is 75% response rate
762 // purchase.EarnedCertificate = true;
763 // result = participantResult.Pass;
767 // result = participantResult.Fail;
770 // Database.SubmitChanges();
774 // ProcessParticipantResult(result, purchase);
776 // return Content("done");
779 public ActionResult Result(int principalid, int scoid) {
780 var resultView = new SessionResultViewModel();
781 participantResult result = participantResult.Wonky;
783 Extensions.LogServiceCall("[IndexController][Result]", string.Format("Beginning: principalid = {0} scoid = {1}", principalid, scoid));
785 Extensions.LogServiceCall("[IndexController][Result]", string.Format(
786 "principalid = {0} scoid = {1} DateTime.UtcNow.DayOfYear = {2} DateTime.Now.DayOfYear = {3}",
787 principalid, scoid, DateTime.UtcNow.DayOfYear, DateTime.Now.DayOfYear));
790 Database.MeetingSessions.FirstOrDefault(
791 m => m.SCO_ID == scoid && m.StartDate.DayOfYear == DateTime.UtcNow.DayOfYear);
792 if(meeting != null) {
793 int msk = meeting.MeetingSessionKey;
794 MeetingParticipantSession meetingParticipantSession =
795 Database.MeetingParticipantSessions.FirstOrDefault(
796 m => m.MeetingSessionKey == msk && m.ParticipantKey == principalid);
797 if(meetingParticipantSession != null) {
798 adobe.GetAdobeTransactions(meetingParticipantSession.MeetingSession, Database);
799 Database.SubmitChanges();
801 result = SessionEnd.ProcessEndOfMeetingSessionHeartbeatResultsForParticipant(Database, meetingParticipantSession);
803 case participantResult.Ineligible:
804 resultView.Message = Utilities.Result.RenderIneligibleResult(principalid);
806 case participantResult.Fail:
807 resultView.Message = Utilities.Result.RenderFailResult(principalid);
809 case participantResult.Pass:
810 resultView.Message = Utilities.Result.RenderPassResult(principalid);
812 case participantResult.Wonky:
813 resultView.Message = Utilities.Result.RenderWonkyResult();
817 Extensions.LogServiceCall("[IndexController][Result]", string.Format(
818 "meetingParticipantSession is null: principalid = {0} scoid= {1} msk = {2}",
819 principalid, scoid, msk));
822 Extensions.LogServiceCall("[IndexController][Result]", string.Format(
823 "meeting is null: principalid = {0} scoid= {1} DateTime.UtcNow.DayOfYear = {2} DateTime.Now.DayOfYear = {3}",
824 principalid, scoid, DateTime.UtcNow.DayOfYear, DateTime.Now.DayOfYear));
826 resultView.Result = (int) result;
827 return View("result", resultView);