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")
30 private bool IsAdmin(string login, string password)
32 return Database.Users.Any(t => t.IsAdmin && t.Login == login && t.Password == password);
35 private bool IsAdmin(string password)
37 return Database.Users.Any(t => t.IsAdmin && t.Password == password);
42 public ActionResult Index(int? year) {
43 if(Request.Cookies["allowed"] == null && !IsLocal())
44 return Redirect("http://www.cpeonline.com/webcasts");
46 //string systemPassword = ConfigurationManager.AppSettings["password"];
47 if (Request.Cookies["allowed"] != null && !IsAdmin(Request.Cookies["allowed"].Value))
49 return Redirect("http://www.cpeonline.com/webcasts");
52 DateTime now = DateTime.UtcNow;
55 year = DateTime.Now.Year;
58 List<MeetingSessionsDataResult> meetingSessions = Database.MeetingSessionsData()
59 .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)))
60 .OrderByDescending(msd => msd.StartDate)
62 return View(meetingSessions);
66 public ActionResult SessionDetails(int meetingSessionKey) {
67 Extensions.LogServiceCall("[IndexController][SessionDetails]", string.Format("Beginning: meetingSessionKey = {0}", meetingSessionKey));
69 var meetingSession = Database.MeetingSessions.Single(ms => ms.MeetingSessionKey == meetingSessionKey);
70 var result = new AdobeSessionViewModel {
71 MeetingSession = meetingSession,
72 ParticipantSessionsDataResult = Database.ParticipantSessionsData(meetingSessionKey)
74 GetSessionReportResult = Database.GetSessionReport(meetingSessionKey)
76 WebcastPurchaseDataResult = Database.WebcastPurchaseData(meetingSession.SCO_ID, meetingSessionKey)
77 //.Where(w => w.Sco == meetingSession.SCO_ID && w.mDate.DayOfYear >= meetingSession.StartDate.DayOfYear)
80 //if (result.ParticipantSessionsDataResult.Count == 0) {
81 adobe.GetAdobeTransactions(meetingSession, Database);
82 Database.SubmitChanges();
84 result = new AdobeSessionViewModel {
85 MeetingSession = meetingSession,
86 ParticipantSessionsDataResult = Database.ParticipantSessionsData(meetingSessionKey)
88 GetSessionReportResult = Database.GetSessionReport(meetingSessionKey)
90 WebcastPurchaseDataResult = Database.WebcastPurchaseData(meetingSession.SCO_ID, meetingSessionKey)
98 public ActionResult RetrieveSession(int meetingSessionKey) {
99 Extensions.LogServiceCall("[IndexController][RetrieveSession]", string.Format("Beginning: meetingSessionKey = {0}", meetingSessionKey));
101 var meetingSession = Database.MeetingSessions.Single(ms => ms.MeetingSessionKey == meetingSessionKey);
102 if(Database.ParticipantSessionsData(meetingSessionKey)
105 adobe.GetAdobeTransactions(meetingSession, Database);
106 Database.SubmitChanges();
109 return RedirectToAction("SessionDetails", new {meetingSessionKey});
114 public ActionResult TestElucidat()
116 var baseUrl = "https://api-launchpad.elucidat.com/";
117 var urlFull = "health/ping";
118 Extensions.LogServiceCall("[IndexController][TestElucidat]", $"Beginning: {baseUrl}{urlFull}");
120 ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Ssl3;
121 ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls;
122 ServicePointManager.SecurityProtocol &= ~SecurityProtocolType.Tls11;
124 ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;
126 var client = new WebClient { BaseAddress = baseUrl };
127 client.Headers.Clear();
128 client.Headers["Accept"] = "application/json";
129 var response = client.DownloadString(urlFull);
130 Extensions.LogServiceCall("[IndexController][TestElucidat]", $"Response: {response}");
133 return Content(response);
137 public ActionResult Login(string meetingUrl, string d = null, string c = null) {
138 meetingUrl = meetingUrl?.Trim();
143 Extensions.LogServiceCall("[IndexController][Login|Get]", string.Format("meetingUrl = {0} d (PurchaseDate) = {1} c (TicketFromUrl) = {2}", meetingUrl, d, c));
145 //Webcast and Rebroadcast access test course
146 if(meetingUrl.ToLower() == "test_room") {
147 var baseUrl = ConfigurationManager.AppSettings["Connect.Url"];
148 var testUrl = ConfigurationManager.AppSettings["Connect.AccessTestMeetingUrl"];
149 var accessTestUrl = baseUrl + '/' + testUrl;
150 return Redirect(accessTestUrl);
152 var meetingType = meetingUrl.Contains('-') ? MeetingType.Elucidat : MeetingType.Adobe;
154 if(meetingType == MeetingType.Elucidat) {
155 var releaseCode = meetingUrl.Substring(meetingUrl.IndexOf('-') + 1);
156 Extensions.LogServiceCall("[IndexController][Login|Get]", string.Format("meetingUrl = {0} releaseCode = {1}", meetingUrl, releaseCode));
158 ReleaseModel release = ElucidatMeetingConnection.GetReleaseDetails(releaseCode);
159 string projectName = null;
160 if(release != null && release.Project != null) {
161 projectName = release.Project.Name;
163 return View("elucidatlogin", new ElucidatCourseView {Name = projectName, Url = meetingUrl, PurchaseDate = d, TicketFromUrl = c, Message = null});
165 //if (ConfigurationManager.AppSettings["CPE.AdobeTicketingOn"].ToLower() == "true")
167 // //The flag is unnecessary now since we're keeping magic passcode access available. Non-ticketed link is now magicTicket
171 XmlDocument meeting = AdobeMeetingConnection.getAdobeMeeting(meetingUrl);
172 if(meeting != null) {
173 if(meeting.SelectSingleNode("//sco")
174 .Attributes["icon"].Value != "archive") {
175 return View("login", new AdobeMeetingView {
176 Name = meeting.SelectSingleNode("//sco/name")
178 HasPassCode = meeting.SelectSingleNode("//meeting-passcode") != null,
188 public ActionResult Login(string meetingUrl, string firstname, string lastname, string email, string passcode,
189 string courseName, string ticket = null, string ticketFromUrl = null, string purchaseDate = null,
190 string message = null) {
191 meetingUrl = meetingUrl?.Trim();
192 firstname = firstname?.Trim();
193 lastname = lastname?.Trim();
194 email = email?.Trim();
195 passcode = passcode?.Trim();
196 courseName = courseName?.Trim();
197 ticket = ticket?.Trim();
198 ticketFromUrl = ticketFromUrl?.Trim();
199 purchaseDate = purchaseDate?.Trim();
200 message = message?.Trim();
202 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));
204 var magicTicketLogin = string.IsNullOrEmpty(ticketFromUrl);
205 var meetingType = meetingUrl.Contains('-') ? MeetingType.Elucidat : MeetingType.Adobe;
207 if(meetingType.Equals(MeetingType.Elucidat)) {
208 var releaseCode = meetingUrl.Substring(meetingUrl.IndexOf('-') + 1);
210 if(!ticket.Equals(ticketFromUrl) ||
211 !VerifyAccess.VerifyTicket(ticket, meetingUrl, firstname, lastname, email, purchaseDate)) {
212 return View("elucidatlogin", new ElucidatCourseView {
215 PurchaseDate = purchaseDate,
216 TicketFromUrl = ticketFromUrl,
218 "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"
223 PurchasedCourse course =
224 Database.PurchasedCourses.SingleOrDefault(pc => pc.Ticket == ticket && pc.ContentUrl == meetingUrl);
227 //no purchase record yet, look for release details in database
228 CourseDetail release = Database.CourseDetails.SingleOrDefault(r => r.ReleaseCode == releaseCode);
229 if(release == null) {
230 //course isn't in db yet, get details form api
231 ReleaseModel releaseCourse = ElucidatMeetingConnection.GetReleaseDetails(releaseCode);
232 var done = ReleaseHelper.GetReleaseDescriptionDetails(releaseCourse);
234 release = Database.CourseDetails.SingleOrDefault(cd => cd.ReleaseCode == releaseCode);
237 string formattedPdate = purchaseDate.Substring(0, 4) + '-' + purchaseDate.Substring(4, 2) + '-' +
238 purchaseDate.Substring(6, 2);
239 DateTime pDate = Convert.ToDateTime(formattedPdate);
240 course = new PurchasedCourse {
241 ContentUrl = meetingUrl,
242 CourseName = release.Name,
243 FirstName = firstname,
247 PurchaseDate = pDate,
248 Presenter = release.Presenter,
250 Credits = release.Credits,
251 CertificateDate = null,
253 isManualCertificate = false
255 Database.PurchasedCourses.InsertOnSubmit(course);
258 Database.SubmitChanges();
260 //verify access (PurchaseDate<1yrold) and access not revoked
261 if(!VerifyAccess.AccessBlocked(course) && VerifyAccess.IsValid(course)) {
262 string courseUrl = ElucidatMeetingConnection.GetLaunchLink(releaseCode, firstname, lastname, email);
264 Regex linkParser = new Regex(@"\b(?:https?://)\S+\b",
265 RegexOptions.Compiled | RegexOptions.IgnoreCase);
266 string rawString = courseUrl;
267 string goodUrl = linkParser.Match(rawString)
270 return Redirect(goodUrl);
273 //Access is expired or Revoked
274 return View("elucidatlogin", new ElucidatCourseView {
277 PurchaseDate = purchaseDate,
278 TicketFromUrl = ticketFromUrl,
280 "Access to this course is no longer available. Please contact Customer Service at 1-800-544-1114 or email us at sswebcast@cpeincmail.com"
284 if((ConfigurationManager.AppSettings["CPE.AdobeTicketingOn"].ToLower() == "true") & !magicTicketLogin) {
285 if(passcode == null) {
286 passcode = (DateTime.UtcNow.ToString("MMM") + DateTime.UtcNow.Day.ToString("00")).ToLower();
288 if(!ticketFromUrl.Equals(ticket)) {
289 return RedirectToAction("Login");
291 if(!VerifyAccess.VerifyTicket(ticket, meetingUrl, firstname, lastname, email, purchaseDate)) {
292 return RedirectToAction("Login");
295 //if valid continue on to existing way of doing things
298 string connectUrl = ConfigurationManager.AppSettings["Connect.Url"];
299 int accountId = int.Parse(ConfigurationManager.AppSettings["Connect.AccountId"]);
300 string password = Guid.NewGuid()
305 Session admin = AdobeMeetingConnection.GetAdobeAdminSession();
306 var request = new Request(admin, "principal-list");
307 request.Parameters.Add("filter-type", "guest");
308 request.Parameters.Add("filter-type", "user");
309 request.Parameters.Add("filter-login", email);
310 if(request.Execute() && request.Status == Status.OK) {
311 Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = [{0}] request.XmlResults.InnerXml = {1}", email, request.XmlResults.InnerXml));
314 if(request.XmlResults.SelectSingleNode("//principal") == null) {
315 principalId = Connect.Login.CreateGuest(admin, email, password, email, firstname, lastname);
317 principalId = int.Parse(request.XmlResults.SelectSingleNode("//principal")
318 .Attributes["principal-id"].Value);
319 email = request.XmlResults.SelectSingleNode("//principal/login")
321 if(request.XmlResults.SelectSingleNode("//principal")
322 .Attributes["type"].Value == "user")
323 return RedirectToAction("Login");
326 return RedirectToAction("Login");
329 Connect.Login.ResetPassword(admin, principalId, password);
330 Session session = Connect.Login.UserLogin(email, password, connectUrl, accountId);
332 var meetingView = new AdobeMeetingView {
333 Name = AdobeMeetingConnection.getAdobeMeetingName(meetingUrl),
334 PrincipalId = principalId,
336 string.Format("{0}/{1}?session={2}&launcher=false", connectUrl, meetingUrl,
337 session.SessionKey) + (passcode == null
339 : "&meeting-passcode=" + passcode)
343 Participant participant = Database.Participants.SingleOrDefault(p => p.Principal_ID == principalId);
344 if(participant == null) {
345 participant = new Participant {
346 Principal_ID = principalId,
347 FirstName = firstname,
351 Database.Participants.InsertOnSubmit(participant);
354 Database.SubmitChanges();
356 var certificateId = 0;
357 int scoId = AdobeMeetingConnection.getAdobeMeetingSco(meetingUrl);
359 if(!magicTicketLogin) {
360 string formattedPdate = purchaseDate.Substring(0, 4) + '-' +
361 purchaseDate.Substring(4, 2) +
362 '-' + purchaseDate.Substring(6, 2);
363 DateTime pDate = Convert.ToDateTime(formattedPdate);
365 ParticipantPurchase purchase =
366 Database.ParticipantPurchases.SingleOrDefault(
368 p.PrincipalID == principalId & p.Ticket == ticketFromUrl &
369 p.MeetingSco == scoId);
370 if(purchase == null) {
371 purchase = new ParticipantPurchase {
372 FirstName = firstname,
375 PrincipalID = principalId,
376 MeetingName = meetingView.Name,
377 MeetingDate = DateTime.UtcNow,
379 Ticket = ticketFromUrl,
380 PurchaseDate = pDate,
381 EarnedCertificate = false,
384 Database.ParticipantPurchases.InsertOnSubmit(purchase);
386 Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = {0} scoId = {1} principalId = {2} MeetingDate = {3}", email, scoId, principalId, purchase.MeetingDate));
389 Database.SubmitChanges();
390 certificateId = purchase.Purchase_ID;
392 meetingView.CertificateId = certificateId;
393 meetingView.ScoId = scoId;
395 Extensions.LogServiceCall("[IndexController][Login|Post]", string.Format("email = {0} scoId = {1} certificateId = {2} principalId = {3}", email, scoId, certificateId, principalId));
397 var idCookie = new HttpCookie("id") {
398 Value = principalId.ToString(),
399 Expires = DateTime.UtcNow.AddDays(1)
401 Response.Cookies.Add(idCookie);
404 request = new Request(admin, "principal-update");
405 request.Parameters.Add("first-name", firstname);
406 request.Parameters.Add("last-name", lastname);
407 request.Parameters.Add("principal-id", principalId.ToString());
410 return View("meeting", meetingView);
412 return RedirectToAction("Login");
416 public ActionResult Admin() {
420 public ActionResult Email() {
421 var email = new MailMessage {
423 "sophia@sophicsystems.com"
425 Subject = "[CPE] Email Test",
426 Body = "Email test has been received.",
427 From = new MailAddress("support@intesolv.com")
429 var server = new SmtpClient("localhost");
432 return Redirect("/");
434 public ActionResult SendCerificateEmail(string email, string url, string key)
436 if (key != "q1w2e3") return Content("Bad key");
437 var course = Database.PurchasedCourses
438 .Where(c => c.Email == email && c.ContentUrl == url)
439 .OrderByDescending(c => c.CertificateDate).FirstOrDefault();
441 var done = SendEmailHelperWeb.SendCertificateEmail(course);
443 var s = url.Split('-');
444 var courseName = Database.CourseDetails
445 .FirstOrDefault(c => c.ReleaseCode == s[1])?.Name;
447 Utilities.LogWrapper.Info("[TinCanHelper][HandleStatement] {0} cert sent email={1} courseName={2}", DateTime.UtcNow.ToString("yyyyMMdd_HHmmss"), email, courseName);
449 return Content("Certificate send successfully");
453 public ActionResult Admin(string login, string passcode) {
454 login = login?.Trim();
455 passcode = passcode?.Trim();
457 // string systemPassword = ConfigurationManager.AppSettings["password"];
458 if(IsAdmin(login, passcode)) {
459 var reportingCookie = new HttpCookie("allowed") {
461 Expires = DateTime.UtcNow.AddDays(1)
463 Response.Cookies.Add(reportingCookie);
465 return Redirect("/");
469 public ActionResult CourseDetails(string releaseCode) {
470 releaseCode = releaseCode?.Trim();
472 var course = Database.CourseDetails.Single(cd => cd.ReleaseCode == releaseCode);
473 var result = new ElucidatCourseViewModel {
474 CourseDetail = course,
475 PurchasedCoursesDataResult = Database.PurchasedCoursesData(releaseCode)
476 .OrderByDescending(pc => pc.PurchaseDate)
484 public ActionResult Elucidat() {
485 if(Request.Cookies["allowed"] == null && !IsLocal())
486 return Redirect("http://www.cpeonline.com/webcasts");
487 // string systemPassword = ConfigurationManager.AppSettings["password"];
488 if(Request.Cookies["allowed"] != null && (!IsAdmin(Request.Cookies["allowed"].Value)))
489 return Redirect("http://www.cpeonline.com/webcasts");
490 DateTime now = DateTime.UtcNow;
492 List<CourseListingsDataResult> courseListings = Database.CourseListingsData()
493 .Where(cl => cl.CreatedDate != null)
494 .OrderBy(cl => cl.Name)
496 return View(courseListings);
500 public ActionResult Wufoo(int id) {
501 //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
502 ParticipantTracking pt = Database.ParticipantTrackings.OrderByDescending(p => p.StartDate)
503 .FirstOrDefault(p => p.Principal_ID == id);
504 string url = ConfigurationManager.AppSettings["Wufoo.Survey1.1"];
506 Extensions.LogServiceCall("[IndexController][Wufoo]", string.Format("id = {0} url = {1}", id, url));
507 return Redirect(url);
510 MeetingDetail d = pt.MeetingParticipantSession.MeetingSession.Meeting.MeetingDetail;
511 DateTime date = Extensions.GetLocalDateTime(DateTime.UtcNow);
512 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);
513 Extensions.LogServiceCall("[IndexController][Wufoo]", string.Format("id = {0} url = {1}", id, url));
514 return Redirect(url);
517 public ActionResult Survey() {
519 string url = ConfigurationManager.AppSettings["Wufoo.Survey1.1"];
520 string cookie = Request.Cookies["id"] == null
522 : Request.Cookies["id"].Value;
523 int.TryParse(cookie, out id);
525 return Redirect(url);
527 Extensions.LogServiceCall("[IndexController][Survey]", string.Format("id = {0}", id));
528 ParticipantTracking pt = Database.ParticipantTrackings.OrderByDescending(p => p.StartDate)
529 .FirstOrDefault(p => p.Principal_ID == id);
531 return Redirect(url);
533 MeetingDetail d = pt.MeetingParticipantSession.MeetingSession.Meeting.MeetingDetail;
534 DateTime date = Extensions.GetLocalDateTime(DateTime.UtcNow);
535 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);
536 return Redirect(url);
540 public ActionResult AllowReporting(Guid? id) {
541 //if (id.HasValue && id == Guid.Parse("")) {
542 // var reportingCookie = new HttpCookie("reporting") {Value = "1", Expires = DateTime.MaxValue};
543 // Response.Cookies.Add(reportingCookie);
544 // return Redirect("/");
546 //return Redirect("http://www.cpeonline.com/webcasts");
547 return RedirectToAction("Admin");
551 public ActionResult GetTicket(string courseUrl) {
552 courseUrl = courseUrl?.Trim();
554 TicketModel ticketInfo = new TicketModel {
555 CourseUrl = courseUrl
557 //return the view as a partial view that opens in a pretty jquery ui form (dialog) within the page, not a new page
558 return PartialView(ticketInfo);
562 public string GetTicket(string firstname, string lastname, string email, string contenturl) {
563 //NOT IMPLEMENTED. possible solution to "magic ticket" request for ondemand course, since a global entry would not make sense
564 //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
566 firstname = firstname?.Trim();
567 lastname = lastname?.Trim();
568 email = email?.Trim();
569 contenturl = contenturl?.Trim();
571 string purchasedate = DateTime.Now.ToString("yyyyMMdd");
572 var ticket = VerifyAccess.generateTicket(contenturl, firstname, lastname, email, purchasedate);
574 var link = "http://cpeonlineselfstudywebcasts.com/" + contenturl + "?d=" + purchasedate + "&c=" + ticket;
578 // GET: CertificateReport
580 public ActionResult CertificateReport() {
581 List<CertficateDataResult> earnedCertificates = Database.CertficateData()
582 .OrderBy(ec => ec.Course)
584 return View(earnedCertificates);
587 public ActionResult WebcastCertificateReport() {
588 List<WebcastCertficateDataResult> earnedCertificates = Database.WebcastCertficateData()
589 .OrderBy(ec => ec.MeetingName)
591 return View(earnedCertificates);
594 //public string SendCert(int meeting_sco, int certificate_id, int principal_id)
596 // //TODO (webcast) make outcome dictionary to return pass, fail, ineligible, or wonky:contact cust serv
597 // string _fail = "fail";
598 // if (certificate_id > 0)
600 // ParticipantPurchase purchase =
601 // Database.ParticipantPurchases.FirstOrDefault(p => p.Purchase_ID == certificate_id && p.PrincipalID == principal_id);
603 // if (purchase == null)
605 // //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
606 // return _fail; // TODO probably return wonky, contact cust service message
609 // if (!purchase.EarnedCertificate)
611 // var meeting = Database.MeetingSessions.FirstOrDefault(
613 // m.Recording == false && m.SCO_ID == meeting_sco &&
614 // m.StartDate.DayOfYear == DateTime.UtcNow.DayOfYear);
615 // if (meeting == null)
617 // return _fail;//TODO return wonky
620 // int meetingSessionKey = meeting.MeetingSessionKey;
622 // MeetingParticipantSession meetingParticipantSession =
623 // Database.MeetingParticipantSessions.FirstOrDefault(
624 // m => m.MeetingSessionKey == meetingSessionKey && m.ParticipantKey == principal_id);
625 // if (meetingParticipantSession == null)
627 // return _fail;//TODO return wonky
630 // List<ParticipantSessionsDataResult> participantSessionsDataResult =
631 // Database.ParticipantSessionsData(meetingSessionKey)
634 // var participantSessionsData =
635 // participantSessionsDataResult.OrderBy(p => p.MeetingParticipantSessionKey)
638 // p.MeetingParticipantSessionKey ==
639 // meetingParticipantSession.MeetingParticipantSessionKey);
641 // if (participantSessionsData == null)
643 // return _fail;//TODO is this a return wonky? it means they weren't tracked
646 // MeetingSessionsDataResult meetingSession = Database.MeetingSessionsData().FirstOrDefault(m => m.MeetingSessionKey == meetingSessionKey);
647 // if (meetingSession == null)
649 // return _fail;//TODO return wonky
652 // var courseLength = meetingSession.ActualSessionTime.GetValueOrDefault(); //in minutes
653 // double courseCredits = courseLength / 50.0; //1 credit per 50 minutes
654 // List<double> maxCourseCredits = ConfigurationManager.AppSettings["MaxCourseCreditList"].Split(';').Select(s => double.Parse(s)).ToList(); //max credits cut list
655 // int mx = maxCourseCredits.BinarySearch(courseCredits); //find appropriate max for this course
656 // double maxCredits = maxCourseCredits[mx >= 0 ? mx : ~mx - 1];//...by rounding down
657 // double realCredits = participantSessionsData.SessionCredit == null ? 0 : (double)participantSessionsData.SessionCredit.Value; //users credits per adobe
658 // purchase.Credits = Math.Min(maxCredits, realCredits); //user awarded no more than max possible credits for the course
660 // MeetingDetail meetingDetail =
661 // Database.MeetingDetails.FirstOrDefault(m => m.MeetingKey == purchase.MeetingSco);
663 // purchase.Presenter = meetingDetail == null ? "" : meetingDetail.Instructor;
665 // double percentComplete = (participantSessionsData.SessionEngagementCount.GetValueOrDefault() == 0 ?
666 // 1 : (participantSessionsData.SessionHeartbeatCount.GetValueOrDefault() / participantSessionsData.SessionEngagementCount.Value));
668 // if (percentComplete >= .75) //threshold for earning a certificate is 75% response rate
670 // purchase.EarnedCertificate = true;
673 // Database.SubmitChanges();
675 // if (purchase.EarnedCertificate)
677 // //TODO with return Pass dictionary value as string.format with replace of certUrl
678 // //string certUrl = AdobeCertificateHelper.SendWebcastCert(purchase);
679 // //format the outcome.pass.value message with certUrl replace
680 // //return outcome.pass with its value
681 // return AdobeCertificateHelper.SendWebcastCert(purchase);
683 // //TODO return outcome.fail
684 // return AdobeCertificateHelper.SendFailNotice(purchase);
687 // return _fail;// TODO return ineligible.need to make AdobeCertificateHelper.SendIneligibleNotice(principalId)
690 //public participantResult ProcessParticipantResult(participantResult result, ParticipantPurchase purchase)
692 // if (purchase == null)
694 // result = participantResult.Ineligible;
698 // case participantResult.Ineligible:
699 // //Ineligible for auto-cert; not sending notice.
701 // case participantResult.Fail:
702 // AdobeCertificateHelper.SendFailNotice(purchase);
704 // case participantResult.Pass:
705 // AdobeCertificateHelper.SendWebcastCert(purchase);
706 // //Send Cert email;
708 // case participantResult.Wonky:
709 // //something went wrong: send email to contact cust service? send email to cpe? do nothing?
715 //public ActionResult BatchProcessParticipantResults(int msk)
717 // List<ParticipantSessionsDataResult> psdr = BaseController.Database.ParticipantSessionsData(msk).ToList();
718 // var meeting = BaseController.Database.MeetingSessions.FirstOrDefault(m => m.MeetingSessionKey == msk);
719 // if (meeting == null)
721 // return Content("Error retrieving meeting session details.");
723 // var scoId = meeting.SCO_ID;
725 // foreach (var p in psdr)
727 // ParticipantPurchase purchase = null;
728 // participantResult result = participantResult.Wonky;
729 // var mpsk = p.MeetingParticipantSessionKey;
730 // var meetingParticipantSession =
731 // BaseController.Database.MeetingParticipantSessions.FirstOrDefault(
732 // mps => mps.MeetingParticipantSessionKey == mpsk && mps.MeetingSessionKey == msk);
734 // if (meetingParticipantSession != null)
736 // var principalId = meetingParticipantSession.ParticipantKey;
738 // purchase = BaseController.Database.ParticipantPurchases.FirstOrDefault(pp => pp.PrincipalID == principalId && pp.MeetingSco == scoId);
739 // if (purchase == null)
741 // result = participantResult.Ineligible;
745 // MeetingSessionsDataResult meetingSession = Database.MeetingSessionsData().FirstOrDefault(m => m.MeetingSessionKey == msk);
746 // if (meetingSession != null)
748 // var courseLength = meetingSession.ActualSessionTime.GetValueOrDefault(); //in minutes
749 // double courseCredits = courseLength/50.0; //1 credit per 50 minutes
750 // List<double> maxCourseCredits =
751 // ConfigurationManager.AppSettings["MaxCourseCreditList"].Split(';')
752 // .Select(s => double.Parse(s))
753 // .ToList(); //max credits cut list
754 // int mx = maxCourseCredits.BinarySearch(courseCredits);
755 // //find appropriate max for this course
756 // double maxCredits = maxCourseCredits[mx >= 0 ? mx : ~mx - 1]; //...by rounding down
757 // double realCredits = p.SessionCredit == null
759 // : (double) p.SessionCredit.Value; //users credits
760 // purchase.Credits = Math.Min(maxCredits, realCredits);
761 // //user awarded no more than max possible credits for the course
763 // MeetingDetail meetingDetail =
764 // Database.MeetingDetails.FirstOrDefault(m => m.MeetingKey == purchase.MeetingSco);
766 // purchase.Presenter = meetingDetail == null ? "" : meetingDetail.Instructor;
768 // double percentComplete =
769 // (p.SessionEngagementCount.GetValueOrDefault() == 0
771 // : (p.SessionHeartbeatCount.GetValueOrDefault()/
772 // p.SessionEngagementCount.Value));
774 // if (percentComplete >= .75) //threshold for earning a certificate is 75% response rate
776 // purchase.EarnedCertificate = true;
777 // result = participantResult.Pass;
781 // result = participantResult.Fail;
784 // Database.SubmitChanges();
788 // ProcessParticipantResult(result, purchase);
790 // return Content("done");
793 public ActionResult Result(int principalid, int scoid) {
794 var resultView = new SessionResultViewModel();
795 participantResult result = participantResult.Wonky;
797 Extensions.LogServiceCall("[IndexController][Result]", string.Format("Beginning: principalid = {0} scoid = {1}", principalid, scoid));
799 Extensions.LogServiceCall("[IndexController][Result]", string.Format(
800 "principalid = {0} scoid = {1} DateTime.UtcNow.DayOfYear = {2} DateTime.Now.DayOfYear = {3}",
801 principalid, scoid, DateTime.UtcNow.DayOfYear, DateTime.Now.DayOfYear));
804 Database.MeetingSessions.FirstOrDefault(
805 m => m.SCO_ID == scoid && m.StartDate.DayOfYear == DateTime.UtcNow.DayOfYear);
806 if(meeting != null) {
807 int msk = meeting.MeetingSessionKey;
808 MeetingParticipantSession meetingParticipantSession =
809 Database.MeetingParticipantSessions.FirstOrDefault(
810 m => m.MeetingSessionKey == msk && m.ParticipantKey == principalid);
811 if(meetingParticipantSession != null) {
812 adobe.GetAdobeTransactions(meetingParticipantSession.MeetingSession, Database);
813 Database.SubmitChanges();
815 result = SessionEnd.ProcessEndOfMeetingSessionHeartbeatResultsForParticipant(Database, meetingParticipantSession);
817 case participantResult.Ineligible:
818 resultView.Message = Utilities.Result.RenderIneligibleResult(principalid);
820 case participantResult.Fail:
821 resultView.Message = Utilities.Result.RenderFailResult(principalid);
823 case participantResult.Pass:
824 resultView.Message = Utilities.Result.RenderPassResult(principalid);
826 case participantResult.Wonky:
827 resultView.Message = Utilities.Result.RenderWonkyResult();
831 Extensions.LogServiceCall("[IndexController][Result]", string.Format(
832 "meetingParticipantSession is null: principalid = {0} scoid= {1} msk = {2}",
833 principalid, scoid, msk));
836 Extensions.LogServiceCall("[IndexController][Result]", string.Format(
837 "meeting is null: principalid = {0} scoid= {1} DateTime.UtcNow.DayOfYear = {2} DateTime.Now.DayOfYear = {3}",
838 principalid, scoid, DateTime.UtcNow.DayOfYear, DateTime.Now.DayOfYear));
840 resultView.Result = (int) result;
841 return View("result", resultView);